cambiada nomenclatura de las páginas y añadidos posts de documentacion-robeasir.surge.sh

main
Roberto Rodríguez 1 year ago
parent 4cf663d7ae
commit 21fee8690e

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

@ -2,7 +2,6 @@
title: "Instalación de Debian desatendida" title: "Instalación de Debian desatendida"
date: 2022-10-06T7:00:09+02:00 date: 2022-10-06T7:00:09+02:00
draft: false draft: false
tags: ["Debian","preseed"]
image: featured.png image: featured.png
categories: categories:
- documentación - documentación

Before

Width:  |  Height:  |  Size: 416 KiB

After

Width:  |  Height:  |  Size: 416 KiB

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 197 KiB

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

@ -2,6 +2,15 @@
title: "Aplicacion web Oracle" title: "Aplicacion web Oracle"
date: 2022-10-30T17:08:54+01:00 date: 2022-10-30T17:08:54+01:00
draft: false draft: false
image: featured.png
categories:
- práctica
- Administración de Bases de Datos
tags:
- Oracle
- apache
- python
- Práctica 1 ABD
--- ---
Aplicación web Oracle programada en python. Aplicación web Oracle programada en python.

@ -10,6 +10,7 @@ tags:
- MariaDB - MariaDB
- Oracle - Oracle
- PostgreSQL - PostgreSQL
- Práctica 1 ABD
--- ---
Vamos a realizar conexiones desde los clientes de BBDD a sus respectivos servidores. Vamos a realizar conexiones desde los clientes de BBDD a sus respectivos servidores.

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

@ -2,6 +2,7 @@
title: "Instalación de MariaDB y PostgreSQL en Debian" title: "Instalación de MariaDB y PostgreSQL en Debian"
date: 2022-10-26T09:32:09+02:00 date: 2022-10-26T09:32:09+02:00
draft: false draft: false
image: featured.png
categories: categories:
- práctica - práctica
- Administración de Bases de Datos - Administración de Bases de Datos

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

@ -0,0 +1,303 @@
---
title: "Práctica 2: Interconexión de Servidores de Bases de Datos"
date: 2022-11-27T14:23:15+01:00
draft: false
image: featured.png
categories:
- práctica
- Administración de Bases de Datos
tags:
- Oracle
- Práctica 2 ABD
---
Las interconexiones de servidores de bases de datos son operaciones que pueden ser muy útiles en
diferentes contextos. Básicamente, se trata de acceder a datos que no están almacenados en nuestra base
de datos, pudiendo combinarlos con los que ya tenemos.
En esta práctica veremos varias formas de crear un enlace entre distintos servidores de bases de datos.
Se pide:
* Realizar un enlace entre dos servidores de bases de datos ORACLE, explicando la configuración
necesaria en ambos extremos y demostrando su funcionamiento.
* Realizar un enlace entre dos servidores de bases de datos Postgres, explicando la configuración
necesaria en ambos extremos y demostrando su funcionamiento.
* Realizar un enlace entre un servidor ORACLE y otro Postgres o MySQL empleando Heterogeneus
Services
## Enlace entre dos servidores ORACLE
En mi caso, las dos máquinas tienen la configuración siguiente; Tienen instalado Rocky 8 Oracle Database 19c Enterprise Edition, y tienen los siguientes nombres e IPs:
* oracle-maquina1: 192.168.122.204
* oracle-maquina2: 192.168.122.80
En ambas bases de datos existe el usuario roberto y están configuradas para el acceso remoto. Para comprobar que pueden acceder se utiliza el comando tnsping:
![1](https://i.imgur.com/gbnsKsB.png)
Ahora, para que los servidores puedan conectarse entre ellos, tenemos que añadir los datos de las máquinas al fichero `/opt/oracle/product/19c/dbhome_1/network/admin/tnsnames.ora`, dejándolos de la siguiente manera:
* En el fichero dentro de la máquina 1:
```ora
MAQUINA2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.122.80)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCLCDB)
)
)
```
* En el fichero dentro de la máquina 2:
```ora
MAQUINA1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.122.80)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = ORCLCDB)
)
)
```
Tras eso hay que crear los enlaces haciendo referencia al usuario (roberto). los comandos se ejecutan dentro de oracle:
* En la máquina 1:
```sql
create database link enlace2 connect to roberto identified by roberto using 'maquina2';
```
* En la máquina 2:
```sql
create database link enlace1 connect to roberto identified by roberto using 'maquina1';
```
Podemos comprobar que se puede acceder remotamente a las tablas:
![2](https://i.imgur.com/iYYIaiL.png)
![3](https://i.imgur.com/2Cu5V0W.png)
## Enlace entre dos servidores Postgres
En mi caso, las dos máquinas tienen la configuración siguiente; Tienen instalado Debian 11,MariaDB y PostgreSQL, y tienen los siguientes nombres e IPs:
* mariadb-maquina1: 192.168.122.97
* mariadb-maquina2: 192.168.122.90
En ambas bases de datos existe el usuario roberto y están configuradas para el acceso remoto.
Ahora vamos a crear el enlace:
```bash
apt install postgresql-contrib
psql -d scott
create extension dblink;
```
Una vez hecho eso, tenemos que ejecutar los siguientes comandos:
* Máquina 1:
```sql
SELECT dblink_connect('dblink2','dbname=scott host=192.168.122.90 user=roberto password=roberto');
```
* Máquina 2:
```sql
SELECT dblink_connect('dblink1','dbname=scott host=192.168.122.97 user=roberto password=roberto');
```
Tras eso, podemos realizar consultas entre máquinas:
![4](https://i.imgur.com/qzn6uGb.png)
---
## Enlace entre un servidor ORACLE y uno Postgres
En este caso las máquinas que voy a conectar son oracle-maquina1 y mariadb-maquina2, por lo que las direcciones IP son las siguientes:
* oracle-maquina1: 192.168.122.204
* mariadb-maquina2: 192.168.122.90
### Conexión desde Postgres a ORACLE
Primero descargamos los siguientes paquetes:
```bash
apt install libaio1 postgresql-server-dev-all build-essential git alien -y
```
Ahora tenemos que descargar el instantclient de oracle, se hace con los siguientes comandos:
```bash
wget https://download.oracle.com/otn_software/linux/instantclient/218000/oracle-instantclient-basic-21.8.0.0.0-1.el8.x86_64.rpm
wget https://download.oracle.com/otn_software/linux/instantclient/218000/oracle-instantclient-devel-21.8.0.0.0-1.el8.x86_64.rpm
wget https://download.oracle.com/otn_software/linux/instantclient/218000/oracle-instantclient-sqlplus-21.8.0.0.0-1.el8.x86_64.rpm
sudo alien -i --scripts oracle-instantclient-*
```
Una vez instalado, con el siguiente comando podemos conectarnos a la base de datos de oracle-maquina1:
```bash
sqlplus roberto/roberto@192.168.122.204:1521/ORCLCDB
```
Ahora tenemos que descargar y compilar `oracle_fdw`:
```bash
wget https://github.com/laurenz/oracle_fdw/archive/refs/tags/ORACLE_FDW_2_5_0.zip
unzip ORACLE_FDW_2_5_0.zip
```
Renombramos la carpeta:
```bash
mv oracle_fdw-ORACLE_FDW_2_5_0/ oracle_fdw
```
Finalmente compilamos el programa:
```bash
cd oracle_fdw
make
make install
```
Ahora, dentro de psql (y de la base de datos scott) creamos el enlace. Podemos comprobar que se ha creado con \dx:
```sql
CREATE EXTENSION oracle_fdw;
```
Creamos el schema en el que se van a importar las bases de datos de Oracle:
```sql
create schema oracle;
```
Configuramos un servidor foráneo que haga referencia a la base de datos Oracle en la otra máquina:
```sql
create server oracle foreign data wrapper oracle_fdw options (dbserver '//192.168.122.204/ORCLCDB');
```
Ahora creamos una equivalencia entre un usuario local y el del servidor (aunque en este caso se llaman igual):
```bash
create user mapping for roberto server oracle options (user 'roberto', password 'roberto');
```
Le damos permisos al usuario local sobre el schema de oracle:
```bash
grant all privileges on schema oracle to roberto;
grant all privileges on foreign server oracle to roberto;
```
Iniciamos sesión en psql con el usuario que hemos indicado en los pasos anteriores, e importamos el esquema remoto:
```bash
psql -U roberto -W -d scott
```
```bash
import foreign schema "ROBERTO" from server oracle into oracle;
```
![5](https://i.imgur.com/EypaWU0.png)
### Conexión desde Oracle a Postgres
Para realizar la conexión vamos a utilizar ODBC (Open Database Conectivity); y en este caso ya que vamos a realizar la conexión con PostgreSQL, también tenemos que descargar el paquete específico:
```bash
dnf install unixODBC postgresql-odbc
```
Ahora en el fichero de configuración `/etc/odbcinst.ini` comentamos todas las líneas menos las referentes a postgresql, quedando el fichero de la siguiente manera:
```bash
[PostgreSQL]
Description = ODBC for PostgreSQL
Driver = /usr/lib/psqlodbcw.so
Setup = /usr/lib/libodbcpsqlS.so
Driver64 = /usr/lib64/psqlodbcw.so
Setup64 = /usr/lib64/libodbcpsqlS.so
FileUsage = 1
```
Para configurar el acceso a la máquina con postgres tenemos que crear en el fichero `/etc/odbc.ini` la siguiente entrada:
```bash
[PSQLU]
Debug = 0
CommLog = 0
ReadOnly = 0
Driver = PostgreSQL
Servername = 192.168.122.90
Username = roberto
Password = roberto
Port = 5432
Database = scott
Trace = 0
TraceFile = /tmp/sql.log
```
Podemos comprobar que funciona con isql PSQLU.
Ahora hay que crear la configuración para que Oracle pueda hacer uso del driver. Para ello tenemos que crear el fichero `/opt/oracle/product/19c/dbhome_1/hs/admin/initPSQLU.ora` con el siguiente contenido:
```bash
HS_FDS_CONNECT_INFO = PSQLU
HS_FDS_TRACE_LEVEL = DEBUG
HS_FDS_SHAREABLE_NAME = /usr/lib64/psqlodbcw.so
HS_LANGUAGE = AMERICAN_AMERICA.WE8ISO8859P1
set ODBCINI=/etc/odbc.ini
```
También hay que configurar el listener `/opt/oracle/product/19c/dbhome_1/network/admin/listener.ora`, añadiendo lo siguiente al final:
```bash
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PSQLU)
(ORACLE_HOME=/opt/oracle/product/19c/dbhome_1)
(PROGRAM=dg4odbc)
)
)
```
Y añadimos una entrada de conexión a `/opt/oracle/product/19c/dbhome_1/network/admin/tnsnames.ora`:
```bash
PSQLU =
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))
(CONNECT_DATA=(SID=PSQLU))
(HS=OK)
)
```
Ahora reiniciamos el listener y creamos el enlace dentro de oracle.
```sql
create database link postgreslink connect to "roberto" identified by"roberto" using 'PSQLU';
```
Ya está creado el enlace. Ahora para comprobar que funciona, podemos hacer una consulta:
```sql
SELECT "ename" FROM "emp"@postgreslink;
```
![6](https://i.imgur.com/rSga9bn.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

@ -0,0 +1,64 @@
---
title: "Compilación Kernel"
date: 2022-12-07T21:18:17+01:00
draft: false
image: featured.png
categories:
- documentación
- Administración de Sistemas Operativos
tags:
- Compilación
- Debian
---
## Compilación de un Kernel linux a medida
Al ser linux un kérnel libre, es posible descargar el código fuente, configurarlo y comprimirlo. Además, esta tarea a priori compleja, es más sencilla de lo que parece gracias a las herramientas disponibles.
En esta tarea debes tratar de compilar un kérnel completamente funcional que reconozca todo el hardware básico de tu equipo y que sea a la vez lo más pequeño posible, es decir que incluya un vmlinuz lo más pequeño posible y que incorpore sólo los módulos imprescindibles. Para ello utiliza el método explicado en clase y entrega finalmente el fichero deb con el kérnel compilado por ti.
El hardware básico incluye como mínimo el teclado, la interfaz de red y la consola gráfica (texto).
## Descarga
En este caso vamos a descargar el último kernel de linux de la [página oficial](https://kernel.org/):
```bash
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.0.7.tar.xz
tar xf linux-6.0.7.tar.xz
cd linux-6.0.7
```
## Compilación del kernel
Para configurar los módulos que tenemos cargados actualmente en el sistema tenemos que introducir losa siguientes comandos:
```bash
make oldconfig
make localyesconfig
```
Con lo siguiente podemos comprobar el número de módulos estáticos y dinámicos que tenemos actualmente:
```bash
egrep '=y' .config | wc -l
egrep '=m' .config | wc -l
```
Para compilar el kernel, tenemos que ejecutar el siguiente comando, que aprovecha el número de núcleos que tenemos para reducir al máximo el tiempo de compilación:
```bash
time make -j $(nproc) bindeb-pkg
```
## Reducir el kernel
Para reducir el tamaño del kernel tenemos que desactivar módulos. Éstos se desactivan ejecutando el siguiente comando:
```bash
make clean
make xconfig
```
que abre una interfaz gráfica en la que podemos seleccionar los módulos quq queremos activar o desactivar:
![https://i.imgur.com/cndWKk6.png](https://i.imgur.com/cndWKk6.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

@ -0,0 +1,610 @@
---
title: "Instalación/migración de aplicaciones web PHP"
date: 2022-12-07T18:15:43+01:00
draft: false
image: featured.png
categories:
- práctica
- Implantación de Aplicaciones Web
tags:
- php
- vagrant
- cms
- mediawiki
- apache
- nginx
- vps
---
## Escenario
Vamos a hacer un escenario de vagrant utilizando el siguiente `Vagrantfile`:
```ruby
Vagrant.configure("2") do |config|
config.vm.define :web do |web|
web.vm.box = "debian/bullseye64"
web.vm.hostname = "servidor-web-roberto"
web.vm.synced_folder ".", "/vagrant", disabled: true
web.vm.network :public_network,
:dev => "bridge0",
:mode => "bridge",
:type => "bridge",
use_dhcp_assigned_default_route: true
web.vm.network :private_network,
:libvirt__network_name => "net1",
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.1",
:libvirt__forward_mode => "veryisolated"
end
config.vm.define :bd do |bd|
bd.vm.box = "debian/bullseye64"
bd.vm.hostname = "servidor-bd-roberto"
bd.vm.synced_folder ".", "/vagrant", disabled: true
bd.vm.network :private_network,
:libvirt__network_name => "net1",
:libvirt__dhcp_enabled => false,
:ip => "10.0.0.2",
:libvirt__forward_mode => "veryisolated"
end
end
```
## Configuración de resolución estática
Vamos a configurar la resolución estática de las páginas utilizando la IP pública de la máquina web:
![resolucion](https://i.imgur.com/n78aYSy.png)
## Instalación de un CMS PHP en mi servidor local
En este caso el CMS que vamos a instalar es [Media Wiki](https://www.mediawiki.org/wiki/Manual:Installing_MediaWiki). Ahora vamos a configurar el servidor y la base de datos.
En el servidor web instalamos apache con php:
```bash
apt update
apt install apache2 libapache2-mod-php php php-mysql
```
### Configuración del VirtualHost
Vamos a instalar el cms en `/var/www/mediawiki`, por lo configuramos el vhost en el fichero `etc/apache2/sites-available/mediawiki.conf`:
```apache2
<VirtualHost *:80>
ServerName www.roberto.org
ServerAdmin webmaster@localhost
DocumentRoot /var/www/mediawiki
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
```
Ahora activamos el VirtualHost
```bash
a2ensite mediawiki
systemctl reload apache2
```
### Configuración de la base de datos
En el servidor que va a tener la base de datos, instalamos mariadb:
```bash
apt update
apt install mariadb-server
mariadb -u root
```
Dentro vamos a crear una base de datos para el CMS y un usuario con permisos:
```sql
GRANT ALL PRIVILEGES ON *.* TO 'remoto'@'%'
IDENTIFIED BY 'remoto' WITH GRANT OPTION;
create database mediawiki;
```
Para configurar el acceso remoto, tenemos que modificar en fichero `/etc/mysql/mariadb.conf.d/50-server.cnf`, la siguiente línea:
```bash
bind-address = 0.0.0.0
```
Y reiniciamos el servicio.
Ahora desde el cliente creamos el siguiente usuario:
```sql
GRANT ALL PRIVILEGES ON *.* TO 'remoto'@'10.0.0.2' IDENTIFIED BY 'remoto' WITH GRANT OPTION;
```
y podemos conectarnos a la base de datos remota con el siguiente comando:
```bash
mysql -u remoto -h 10.0.0.2 --password=remoto
```
### Instalación MediaWiki
Para instalar media wiki, tenemos que descargar la última versión de la página oficial:
```bash
wget https://releases.wikimedia.org/mediawiki/1.38/mediawiki-1.38.4.tar.gz
tar -xf mediawiki-1.38.4.tar.gz
cp -r mediawiki-1.38.4/* /var/www/mediawiki/
chown -R www-data:www-data /var/www/mediawiki/
```
Antes de iniciar la instalación tenemos que instalar los siguientes paquetes:
```bash
apt install php-mbstring php-xml php-intl -y
systemctl restart apache2.service
```
Ahora seguimos la instalación normalmente, pero en la configuración de la base de datos es importante especificar la IP:
![p2-1](https://i.imgur.com/lUVzDxN.png)
Una vez finalizada la configuración inicial, se descarga el fichero `LocalSettings.php`:
![p2-2](https://i.imgur.com/Ecn7gng.png)
Tenemos que moverlo al Document Root de MediaWiki:
```bash
chown www-data:www-data LocalSettings.php
mv LocalSettings.php /var/www/mediawiki/
```
Una vez realizada la configuración, accediendo a `www.roberto.org` aparece la wiki:
![p2-3](https://i.imgur.com/mT4mBno.png)
#### Instalación de un módulo
Tras configurar el tema, vamos a instalar un módulo: [SimpleCalendar](https://www.mediawiki.org/wiki/Extension:SimpleCalendar):
```bash
wget https://extdist.wmflabs.org/dist/extensions/SimpleCalendar-REL1_38-b7a2f05.tar.gz
tar -xf SimpleCalendar-REL1_38-b7a2f05.tar.gz
mv SimpleCalendar /var/www/mediawiki/extensions/
```
Ahora añadimos la siguiente línea al final de `LocalSettings.php`:
```bash
echo "wfLoadExtension( 'SimpleCalendar' );" >> /var/www/mediawiki/LocalSettings.php
```
Una vez hecho, podemos comprobar que está correctamente instalado accediendo a [http://www.roberto.org/index.php/Especial:Versión](http://www.roberto.org/index.php/Especial:Versi%C3%B3n)
![p2-4](https://i.imgur.com/GYSoi3r.png)
Ya instalado, podemos añadir calendarios a las páginas de la wiki con el siguiente bloque:
```php
{{#calendar: year=2022 | month=nov | title="calendario" }}
```
Y quedaría de la siguiente forma:
![p2-5](https://i.imgur.com/bNKXNG6.png)
## Instalación del CMS PHP NextCloud
Primero descargamos la última versión y lo movemos al directorio de apache:
```bash
wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest.zip
cp -r nextcloud/ /var/www/
chown -R www-data:www-data /var/www/nextcloud/
```
Ahora configuramos el vhost en el fichero `etc/apache2/sites-available/nextcloud.conf`:
```bash
<VirtualHost *:80>
ServerName www.cloud.roberto.org
ServerAdmin webmaster@localhost
DocumentRoot /var/www/nextcloud
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
```
```bash
a2ensite nextcloud.conf
systemctl reload apache2.service
```
E instalamos los módulos de php necesarios:
```bash
apt install php-zip php-gd php-curl -y
systemctl reload apache2.service
```
Ahora en la máquina con la base de datos creamos la base de datos para nextcloud:
```bash
create database nextcloud;
```
Tras este paso, podemos acceder a `cloud.roberto.org` para iniciar la instalación, es importante que en la base de datos especifiquemos la ip y el puerto de la máquina con la base de datos:
![p2-6](https://i.imgur.com/dSKyF4C.png)
Una vez finalizada la instalación, ya podremos utilizar nextcloud:
![p2-7](https://i.imgur.com/LKyMGco.png)
---
## DNS del dominio
Para configurar el dns tenemos que mirar la dirección en la configuración del VPS:
![p2-8](https://i.imgur.com/MZtPIqH.png)
y añadir un registro CNAME en la dirección [www.admichin.es](www.admichin.es) que lleve a esa dirección:
![p2-9](https://i.imgur.com/hnTB39X.png)
## Configuración del servidor LEMP
Para instalar el servidor lemp tenemos que instalar los siguientes paquetes:
```bash
apt install
apt install nginx php php-mysql mariadb-server -y
```
Ahora, en la máquina con la base de datos, creamos un fichero con la copia de seguridad y lo enviamos a la vps:
```bash
mysqldump -u remoto -p -x -A > dbs.sql
scp dbs.sql calcetines@nodriza.admichin.es:/home/calcetines
```
Ahora creamos en la base de datos un usuario con permisos y restauramos las bases de datos:
```sql
GRANT ALL PRIVILEGES ON *.* TO 'admin'@localhost IDENTIFIED BY 'contraseña' WITH GRANT OPTION;
```
```bash
mysql --user admin --password < dbs.sql
```
## Migración de las aplicaciones
Para migrar las aplicaciones, tenemos que moverlas al servidor. En este caso utilizaré rsync ya que permite reanudar la transmisión si se interrumpe, además de ser más rápido que scp:
```bash
rsync -avP /var/www/mediawiki/ calcetines@nodriza.admichin.es:/home/calcetines/mediawiki
rsync -avP /var/www/nextcloud/ calcetines@nodriza.admichin.es:/home/calcetines/nextcloud
```
Una vez finalizado, en este caso vamos a utilizar un solo virtualhost, por lo que los directorios de ambas aplicaciones deben estar en `/var/www/html/nombreaplicacion`:
```bash
upstream php-handler {
#server 127.0.0.1:9000;
server unix:/var/run/php/php7.4-fpm.sock;
}
# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
"" "";
default "immutable";
}
server {
listen 80;
listen [::]:80;
server_name www.admichin.es;
# Prevent nginx HTTP Server Detection
#server_tokens off;
rewrite ^/$ /portal;
# Path to the root of the domain
root /var/www/html;
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in the cloud `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /cloud/remote.php/dav/; }
location = /.well-known/caldav { return 301 /cloud/remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let cloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /cloud/index.php$request_uri;
}
location ^~ /portal {
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
client_body_buffer_size 512k;
# HTTP response headers borrowed from cloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
fastcgi_hide_header X-Powered-By;
index index.php index.html /portal/index.php$request_uri;
location ~ \.php(?:$|/) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_max_temp_file_size 0;
}
location /portal {
try_files $uri $uri/ /portal/index.php$request_uri;
}
}
location ~ /\.ht {
deny all;
}
location ^~ /cloud {
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# HTTP response headers borrowed from cloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
index index.php index.html /cloud/index.php$request_uri;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = /cloud {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /cloud/remote.php/webdav/$is_args$args;
}
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/cloud/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/cloud/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/cloud/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /cloud/index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
# fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_max_temp_file_size 0;
}
location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
try_files $uri /cloud/index.php$request_uri;
add_header Cache-Control "public, max-age=15778463, $asset_immutable";
access_log off; # Optional: Don't log access to assets
location ~ \.wasm$ {
default_type application/wasm;
}
}
location ~ \.woff2?$ {
try_files $uri /cloud/index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /cloud/remote {
return 301 /cloud/remote.php$request_uri;
}
location /cloud {
try_files $uri $uri/ /cloud/index.php$request_uri;
}
}
}
```
### MediaWiki
para migrar la aplicación de mediawiki tenemos que realizar los siguientes pasos:
* Primero tenemos que transferir los ficheros que se encuentren en el document root de mediawiki a la vps, en este caso con rsync:
```bash
rsync -avP /var/www/mediawiki/ calcetines@nodriza.admichin.es:/home/calcetines/mediawiki
```
* dentro de la vps lo movemos a su nueva ubicación:
```bash
mv mediawiki /var/www/html/portal
```
* El último paso, es configurar el fichero `LocalSettings.php` (he quitado los comentarios para que sea menos largo):
```php
<?php
if ( !defined( 'MEDIAWIKI' ) ) { exit;
}
$wgSitename = "adMICHIn.es"; $wgMetaNamespace = "AdMICHIn.es";
$wgScriptPath = "/portal";
$wgServer = "http://www.admichin.es";
$wgResourceBasePath = $wgScriptPath;
$wgLogos = [ '1x' => "https://i.imgur.com/KqnlgCE.png",
'icon' => "https://i.imgur.com/KqnlgCE.png", ];
$wgEnableEmail = true; $wgEnableUserEmail = true; # UPO $wgEmergencyContact = "apache@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.invalid"; $wgPasswordSender =
"apache@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.invalid"; $wgEnotifUserTalk = false; # UPO $wgEnotifWatchlist = false; # UPO $wgEmailAuthentication = true;
$wgDBtype = "mysql"; $wgDBserver = "localhost"; $wgDBname = "mediawiki"; $wgDBuser = "admin"; $wgDBpassword =
"contraseña";
$wgDBprefix = "";
$wgDBTableOptions = "ENGINE=InnoDB, DEFAULT CHARSET=binary";
$wgSharedTables[] = "actor";
$wgMainCacheType = CACHE_NONE; $wgMemCachedServers = [];
$wgEnableUploads = false;
$wgUseInstantCommons = false;
$wgPingback = true;
$wgLanguageCode = "es";
$wgLocaltimezone = "UTC";
$wgSecretKey = "61c7675d604b7bd8b0b434dd7c53d6470ff8797636136e4ef7ade0e08cdaba14";
$wgAuthenticationTokenVersion = "1";
$wgUpgradeKey = "696787eac8f24d0f";
$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright $wgRightsUrl = ""; $wgRightsText =
""; $wgRightsIcon = "";
$wgDiff3 = "/usr/bin/diff3";
$wgDefaultSkin = "MonoBook";
wfLoadSkin( 'MinervaNeue' ); wfLoadSkin( 'MonoBook' ); wfLoadSkin( 'Timeless' ); wfLoadSkin( 'Vector' );
wfLoadExtension( 'SimpleCalendar' );
$wgUsePathInfo = TRUE;
```
Tras eso mediaWiki estaría totalmente configurado y podremos acceder con: [http://www.admichin.es](http://www.admichin.es)
![m1](https://i.imgur.com/3BgNcj6.png)
### NextCloud
Para migrar nextcloud, el método es diferente. Siguiendo [guía oficial](https://docs.nextcloud.com/server/latest/admin_manual/maintenance/migrating.html) hay que seguir los siguientes pasos:
* En la vps, tenemos que instalar los requisitos previos de nextcloud
```bash
pt install php-zip php-gd php-curl -y
```
* En la máquina original, hay que activar el modo mantenimiento del Nextcloud (desde el document root de nextcloud) y apagar el servidor tras 6-7 minutos:
```bash
sudo -u www-data php occ maintenance:mode --on
systemctl stop apache2
```
![m2](https://i.imgur.com/gFqYaJ9.png)
* Cuando termine copiamos los ficheros de nextcloud a la vps:
```bash
rsync -avP /var/www/nextcloud/ calcetines@nodriza.admichin.es:/home/calcetines/nextcloud
```
* Dentro de la vps lo movemos a su nueva ubicación:
```bash
mv nextcloud /var/www/html/cloud
```
* en el fichero config.php tenemos que adaptar las opciones:
```php
<?php
$CONFIG = array (
'instanceid' => 'oct5tjcnoj2h',
'passwordsalt' => 'uz7Kh0ZsihYsbbhIhL/HojMYSVc20y',
'secret' => 'NxO/97NF1AoG+oCMrY3ryaefvSGO6SHczYjoc5x8NvsLZ1ma',
'trusted_domains' =>
array (
0 => 'www.admichin.es',
),
'datadirectory' => '/var/www/html/cloud/data',
'dbtype' => 'mysql',
'version' => '25.0.1.1',
'overwrite.cli.url' => 'http://www.admichin.es/cloud',
'dbname' => 'nextcloud',
'dbhost' => 'localhost',
'dbport' => '',
'dbtableprefix' => 'oc_',
'mysql.utf8mb4' => true,
'dbuser' => 'oc_roberto',
'dbpassword' => '}QR947P6^,vV%K$ATu]$W~%)AUhj6X',
'installed' => true,
'maintenance' => true,
);
```
* Ahora, teniendo en cuenta que el serverblock de nginx está configurado, comprobamos que al acceder a [http://www.admichin.es/cloud](http://www.admichin.es/cloud) aparece el modo mantenimiento.
* Si aparecece la misma imagen que en el caso anterior, entonces podemos cambiar el valor de configuración de `mainteinance` a false, y recargamos la página:
![m3](https://i.imgur.com/7jYwYOI.png)
![m4](https://i.imgur.com/06VeYQ7.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

@ -0,0 +1,421 @@
---
title: "Práctica PL/SQL individual"
date: 2022-12-07T13:37:02+01:00
draft: false
image: featured.png
categories:
- documentación
- Administración de Bases de Datos
tags:
- Oracle
- PL/SQL
---
## Hacer un procedimiento que muestre el nombre y el salario del empleado cuyo código es 7782
```sql
CREATE OR REPLACE PROCEDURE mostrarnombresalario
is
v_nombre emp.ename%type;
v_salario emp.sal%type;
begin
select ename,sal into v_nombre,v_salario from emp where empno=7782;
dbms_output.put_line('El nombre del empleado es ' || v_nombre || ' y su salario es: ' || v_salario);
end;
/
```
![p1](https://i.imgur.com/CscMTfL.png)
## Hacer un procedimiento que reciba como parámetro un código de empleado y devuelva su nombre
```sql
CREATE OR REPLACE PROCEDURE mostrarnombresalario2 (p_empno emp.empno%TYPE)
is
v_nombre emp.ename%type;
v_salario emp.sal%type;
begin
select ename,sal into v_nombre,v_salario from emp where empno=p_empno;
dbms_output.put_line('El nombre del empleado es ' || v_nombre || ' y su salario es: ' || v_salario);
end;
/
```
![p2](https://i.imgur.com/o2tqMaP.png)
## Hacer un procedimiento que devuelva los nombres de los tres empleados más antiguos
```sql
CREATE OR REPLACE PROCEDURE topantiguos
is
cursor c_top is
select ename
from emp
order by hiredate asc
fetch first 3 rows only;
begin
dbms_output.put_line('Los 3 empleados mas antiguos son: ');
for v_empleado in c_top loop
dbms_output.put_line(v_empleado.ename);
end loop;
end;
/
```
![p3](https://i.imgur.com/FOSjg5a.png)
## Hacer un procedimiento que reciba el nombre de un tablespace y muestre los nombres de los usuarios que lo tienen como tablespace por defecto (Vista DBA_USERS)
```sql
CREATE OR REPLACE PROCEDURE verusuarios (p_tablespace dba_users.default_tablespace%type)
is
cursor c_usuarios is
SELECT username
from dba_users
where default_tablespace=p_tablespace;
begin
dbms_output.put_line('El tablespace ' || p_tablespace || ' es el predeterminado de los siguientes usuarios:');
for v_usuario in c_usuarios loop
dbms_output.put_line(v_usuario.username);
end loop;
end;
/
```
![p4](https://i.imgur.com/U3oRByX.png)
## Modificar el procedimiento anterior para que haga lo mismo pero devolviendo el número de usuarios que tienen ese tablespace como tablespace por defecto. Nota: Hay que convertir el procedimiento en función
```sql
CREATE OR REPLACE function f_numusuarios (p_tablespace dba_users.default_tablespace%type)
return number
is
v_num number;
begin
select count(username) into v_num from dba_users where default_tablespace=p_tablespace;
return v_num;
end;
/
```
## Hacer un procedimiento llamado mostrar_usuarios_por_tablespace que muestre por pantalla un listado de los tablespaces existentes con la lista de usuarios de cada uno y el número de los mismos, así: (Vistas DBA_TABLESPACES y DBA_USERS)
```sql
Tablespace xxxx:
Usr1
Usr2
...
Total Usuarios Tablespace xxxx: n1
Tablespace yyyy:
Usr1
Usr2
...
Total Usuarios Tablespace yyyy: n2
....
Total Usuarios BD: nn
```
He modificado el procedimiento del ejercicio 4:
```sql
CREATE OR REPLACE PROCEDURE verusuarios (p_tablespace dba_users.default_tablespace%type)
is
cursor c_usuarios is
SELECT username
from dba_users
where default_tablespace=p_tablespace;
begin
for v_usuario in c_usuarios loop
dbms_output.put_line(CHR(9)|| v_usuario.username);
end loop;
end;
/
```
Y el procedimiento nuevo es:
```sql
CREATE OR REPLACE PROCEDURE mostrar_usuarios_por_tablespace
is
cursor c_tablespaces is
SELECT tablespace_name
from dba_tablespaces;
v_total_usuario number;
v_total number:=0;
begin
for v_tablespace in c_tablespaces loop
dbms_output.put_line('Tablespace ' || v_tablespace.tablespace_name);
verusuarios(v_tablespace.tablespace_name);
v_total_usuario:=f_numusuarios(v_tablespace.tablespace_name);
v_total:=v_total+v_total_usuario;
dbms_output.put_line('Total Usuarios tablespace ' || v_tablespace.tablespace_name || ': ' || v_total_usuario);
end loop;
dbms_output.put_line('Total Usuarios BD : ' || v_total);
end;
/
```
![p5](https://i.imgur.com/1sCHBpU.png)
[...]
![p6](https://i.imgur.com/pbjFtsP.png)
## Hacer un procedimiento llamado mostrar_codigo_fuente que reciba el nombre de otro procedimiento y muestre su código fuente. (DBA_SOURCE)
```sql
CREATE OR REPLACE PROCEDURE mostrar_codigo_fuente (p_nombre dba_source.name%type)
is
cursor c_codigo is
SELECT text
from dba_source
where name=p_nombre;
begin
for v_codigo in c_codigo loop
dbms_output.put_line(v_codigo.text);
end loop;
end;
/
```
![p7](https://i.imgur.com/zx9BQyp.png)
## Hacer un procedimiento llamado mostrar_privilegios_usuario que reciba el nombre de un usuario y muestre sus privilegios de sistema y sus privilegios sobre objetos. (DBA_SYS_PRIVS y DBA_TAB_PRIVS)
```sql
CREATE OR REPLACE PROCEDURE mostrar_privilegios_usuario (p_nombre dba_source.name%type)
is
cursor c_sistema is
SELECT privilege
from dba_sys_privs
where grantee=p_nombre
and ADMIN_OPTION='YES'
OR INHERITED='YES';
cursor c_objetos is
SELECT privilege,table_name
from dba_tab_privs
where grantee=p_nombre;
begin
dbms_output.put_line('Privilegios del usuario '|| p_nombre || ' de sistema');
for v_sistema in c_sistema loop
dbms_output.put_line(CHR(9)||v_sistema.privilege);
end loop;
dbms_output.put_line('Privilegios del usuario '|| p_nombre || ' sobre objetos');
for v_objeto in c_objetos loop
dbms_output.put_line(CHR(9)||v_objeto.privilege || '---' || v_objeto.table_name);
end loop;
end;
/
```
![p8](https://i.imgur.com/V9bkArM.png)
## Realiza un procedimiento llamado listar_comisiones que nos muestre por pantalla un listado de las comisiones de los empleados agrupados según la localidad donde está ubicado su departamento con el siguiente formato:
```sql
Localidad NombreLocalidad
Departamento: NombreDepartamento
Empleado1 ……. Comisión 1
Empleado2 ……. Comisión 2
.
.
.
Empleadon ……. Comision n
Total Comisiones en el Departamento NombreDepartamento: SumaComisiones
Departamento: NombreDepartamento
Empleado1 ……. Comisión 1
Empleado2 ……. Comisión 2
.
.
.
Empleadon ……. Comision n
Total Comisiones en el Departamento NombreDepartamento: SumaComisiones
.
.
Total Comisiones en la Localidad NombreLocalidad: SumaComisionesLocalidad
Localidad NombreLocalidad
.
.
Total Comisiones en la Empresa: TotalComisiones
```
Nota: Los nombres de localidades, departamentos y empleados deben aparecer por orden alfabético.
Si alguno de los departamentos no tiene ningún empleado con comisiones, aparecerá un mensaje informando de ello en lugar de la lista de empleados.
El procedimiento debe gestionar adecuadamente las siguientes excepciones:
a) La tabla Empleados está vacía.
b) Alguna comisión es mayor que 10000.
He creado dos funciones y un procedimiento:
```sql
CREATE OR REPLACE FUNCTION listar_empleados(p_deptno dept.deptno%type)
return number
is
cursor c_empleados is
SELECT ename,comm
from emp
where deptno=p_deptno
order by ename;
v_vacio number;
v_suma number:=0;
v_valor number;
begin
select sum(comm) into v_vacio from emp where deptno=p_deptno;
if v_vacio>0 then
for v_empleado in c_empleados loop
IF v_empleado.comm is NULL THEN
v_valor:=0;
ELSE
v_suma:=v_suma+v_empleado.comm;
v_valor:=v_empleado.comm;
END IF;
dbms_output.put_line(CHR(9)||CHR(9)|| v_empleado.ename || ' ... ' || v_valor);
end loop;
else
dbms_output.put_line(CHR(9)||CHR(9)|| 'El departamento no tiene comisiones');
end if;
return v_suma;
EXCEPTION
WHEN NO_DATA_FOUND then
dbms_output.put_line('La tabla empleados está vacía');
return 0;
end;
/
CREATE OR REPLACE FUNCTION listar_departamentos(p_loc dept.loc%type)
return number
is
cursor c_departamentos is
SELECT dname,deptno
from dept
where loc=p_loc
order by dname;
v_total number;
v_suma number:=0;
begin
for v_departamento in c_departamentos loop
dbms_output.put_line(CHR(9)|| 'Departamento: ' || v_departamento.dname);
v_total:=listar_empleados(v_departamento.deptno);
dbms_output.put_line(CHR(9)|| 'Total Comisiones en el Departamento ' || v_departamento.dname || ': ' || v_total);
v_suma:=v_suma+v_total;
end loop;
return v_suma;
end;
/
CREATE OR REPLACE PROCEDURE listar_comisiones
is
cursor c_localidades is
SELECT loc
from dept
order by loc;
v_total number;
v_suma number:=0;
begin
for v_localidad in c_localidades loop
dbms_output.put_line('Localidad ' || v_localidad.loc);
v_total:=listar_departamentos(v_localidad.loc);
dbms_output.put_line('Total Comisiones en la Localidad ' || v_localidad.loc || ': ' || v_total);
v_suma:=v_suma+v_total;
end loop;
dbms_output.put_line('Total Comisiones de la Empresa ' || v_suma);
end;
/
```
![p9](https://i.imgur.com/DGWQS1b.png)
## . Realiza un procedimiento que reciba el nombre de una tabla y muestre los nombres de las restricciones que tiene, a qué columna afectan y en qué consisten exactamente. (DBA_TABLES, DBA_CONSTRAINTS, DBA_CONS_COLUMNS)
He realizado los siguientes procedimientos:
```sql
CREATE OR REPLACE PROCEDURE listar_restriccion(p_nombre user_constraints.table_name%type,p_tabla user_constraints.table_name%type)
is
v_tipo user_constraints.constraint_type%type;
v_nombre user_constraints.constraint_name%type;
v_referencia user_constraints.r_constraint_name%type;
v_condicion user_constraints.search_condition%type;
begin
select constraint_name,constraint_type,r_constraint_name,search_condition into v_nombre,v_tipo,v_referencia,v_condicion
from user_constraints
where table_name = p_tabla
and constraint_name=p_nombre;
if v_tipo='P' then
dbms_output.put_line(p_nombre || ' ... es de tipo CLAVE PRIMARIA');
elsif v_tipo='R' then
dbms_output.put_line(p_nombre || ' ... es de tipo CLAVE EXTERNA y hace referencia a: ' || v_nombre);
elsif v_tipo='C' then
dbms_output.put_line(p_nombre || ' ... es de tipo CHECK y contiene la siguiente comprobacion: ' || v_condicion);
end if;
end;
/
CREATE OR REPLACE PROCEDURE listar_restricciones(p_tabla user_constraints.table_name%type)
is
cursor c_columnas is
SELECT constraint_name,column_name
from user_cons_columns
where table_name=p_tabla;
begin
dbms_output.put_line('Restricciones de la tabla ' || p_tabla);
for v_columna in c_columnas loop
listar_restriccion(v_columna.constraint_name,p_tabla);
dbms_output.put_line(CHR(9)||'Hace referencia a la columna -> ' || v_columna.column_name);
end loop;
end;
/
```
En la comprobación introduzco una tabla diferente al esquema SCOTT ya que tiene más restricciones:
![p10](https://i.imgur.com/OMoSRQz.png)
## Realiza al menos dos de los ejercicios anteriores en Postgres usando PL/pgSQL.
## Ejercicio 1
```sql
CREATE or replace PROCEDURE mostrarnombresalario() AS $$
DECLARE
v_nombre emp.ename%type;
v_salario emp.sal%type;
BEGIN
select ename,sal into v_nombre,v_salario from emp where empno=7782;
RAISE NOTICE 'El nombre del empleado es %, y su salario es %', v_nombre,v_salario;
END;
$$ LANGUAGE plpgsql;
```
![p11](https://i.imgur.com/GifaOGt.png)
## Ejercicio 2
```sql
CREATE or replace PROCEDURE mostrarnombresalario2(p_empno emp.empno%type) AS $$
DECLARE
v_nombre emp.ename%type;
BEGIN
select ename into v_nombre from emp where empno=7782;
RAISE NOTICE 'El nombre del empleado cuyo codigo es %, es %', p_empno,v_nombre;
END;
$$ LANGUAGE plpgsql;
```
![p12](https://i.imgur.com/OKfLC2X.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

@ -0,0 +1,122 @@
---
title: "Montaje NFS mediante systemd"
date: 2022-12-15T13:24:40+01:00
draft: false
image: featured.png
categories:
- documentación
- Administración de Sistemas Operativos
tags:
- NFS
- Openstack
- Debian
---
En una instancia del cloud, basada en la distribución de tu elección, anexa un volumen de 2GB. En dicha instancia deberás configurar el servicio nfs de exportación y en el volumen un punto de montaje de la exportación mediante systemd.
### Escenario
El escenario se compone de dos máquinas, alfa, con debian 11 y que será el servidor nfs; y bravo, con rocky linux 8 y que será el cliente nfs.
## Servidor NFS
Instalamos los paquetes necesarios para el servicio nfs:
```bash
apt install nfs-kernel-server nfs-common
```
Creamos el fichero `/etc/systemd/system/mnt-carpeta.mount` con el siguiente contenido. El nombre del fichero, tiene que ser el mismo que el del punto de montaje en el que vamos a montar el dispositivo, además de sustituyendo las "/" por "-" (menos la primera):
```bash
[Unit]
Description=Montaje de disco para compartir
[Mount]
What= /dev/vdb
Where= /mnt/carpeta/
Type=ext4
Options=defaults
[Install]
WantedBy=multi-user.target
```
Activamos el servicio:
```bash
systemctl enable mnt-carpeta.mount
systemctl start mnt-carpeta.mount
```
Si no funciona el montaje de la unidad, podemos comprobar os errores con `journalctl -xe`
Tras el montaje podemos comprobar que el disco se ha montado correctamente:
![Montaje de disco](https://i.imgur.com/8cUkODO.png)
Finalmente, añadimos la siguiente línea al fichero `/etc/exports`:
```bash
/mnt/carpeta 172.16.0.0/16(rw,no_all_squash,no_subtree_check)
```
Y reiniciamos el servicio:
```bash
systemctl restart nfs-server
```
## Cliente NFS
Instalamos los paquetes necesarios para el servicio nfs:
```bash
dnf install nfs-utils
```
Podemos ver los dispositivos de bloques que se están compartiendo por nfs (la ip del servidor nfs es `172.16.0.1`):
```bash
showmount -e 172.16.0.1
```
![Dispositivos compartidos](https://i.imgur.com/oaYEhYA.png)
Creamos el fichero `/etc/systemd/system/mnt-carpetaNFS.mount` con el siguiente contenido:
```bash
[Unit]
Description=Montaje del disco compartido por red usando NFS
[Mount]
What=172.16.0.1:/mnt/carpeta
Where=/mnt/carpetaNFS
Type=nfs
Options=defaults
[Install]
WantedBy=multi-user.target
```
Activamos el servicio:
```bash
systemctl enable mnt-carpetaNFS.mount
systemctl start mnt-carpetaNFS.mount
```
Podemos comprobar que el disco se ha montado correctamente:
![Montaje de disco 2](https://i.imgur.com/l4fEpSh.png)
## Comprobación
Comprobamos que el dispositivo de bloques se está compartiendo por nfs:
![Comprobación](https://i.imgur.com/16NCruU.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

@ -0,0 +1,213 @@
---
title: "Escenario Dns"
date: 2022-12-19T14:01:03+01:00
draft: false
image: featured.png
categories:
- práctica
- Servicios de Red e Internet
tags:
- DNS
- Openstack
- bind9
---
El enunciado de la prácica se encuentra en el siguiente [enlace](https://fp.josedomingo.org/sri2223/5_dns/practica.html)
## 1. Configuración DNS de cada máquina
Para no tocar la configuración de los servidores DHCP de **OpenStack**, cambiamos manualmente la configuración de las máquinas **Alfa, Bravo y Delta** para que tengan como servidor DNS el servidor **bind9** en **Charlie**, así como el dns del centro (Babuino). Para ello, editamos el fichero `/etc/resolv.conf` y añadimos las siguientes líneas:
```bash
nameserver 192.168.0.2
nameserver 192.168.202.2
```
Para hacer los cambios persistentes en debian/ubuntu, instalamos el paquete `resolvconf`y añadimos los dns al final del fichero `/etc/resolvconf/resolv.conf.d/head`. Para aplicar los cambios sin tener que reiniciar tenemos que ejecutar el comando `resolvconf -u`.
#### VISTAS
```bash
view interna {
match-clients { 192.168.0.0/24; 127.0.0.1; };
allow-recursion { any; };
zone "roberto.gonzalonazareno.org"
{
type master;
file "db.interna.roberto.gonzalonazareno.org";
};
zone "0.168.192.in-addr.arpa"
{
type master;
file "db.0.168.192";
};
zone "16.172.in-addr.arpa"
{
type master;
file "db.0.16.172";
};
include "/etc/bind/zones.rfc1918";
include "/etc/bind/named.conf.default-zones";
};
view dmz {
match-clients { 172.16.0/16;};
allow-recursion { any; };
zone "roberto.gonzalonazareno.org"
{
type master;
file "db.dmz.roberto.gonzalonazareno.org";
};
zone "16.172.in-addr.arpa"
{
type master;
file "db.16.172";
};
include "/etc/bind/zones.rfc1918";
include "/etc/bind/named.conf.default-zones";
};
view externa {
match-clients { 172.22.0.0/16; 172.29.0.0/16; 192.168.202.2; };
allow-recursion { any; };
zone "roberto.gonzalonazareno.org"
{
type master;
file "db.externa.roberto.gonzalonazareno.org";
};
include "/etc/bind/zones.rfc1918";
include "/etc/bind/named.conf.default-zones";
};
```
## Definición de las zonas
### INTERNA /var/cache/bind/db.interna.roberto.gonzalonazareno.org
```bash
$TTL 86400
@ IN SOA charlie.roberto.gonzalonazareno.org. root.roberto.gonzalonazareno.org. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
86400 ) ; Negative Cache TTL
;
@ IN NS charlie.roberto.gonzalonazareno.org.
@ IN MX 10 mail.roberto.gonzalonazareno.org.
$ORIGIN roberto.gonzalonazareno.org.
alfa IN A 192.168.0.1
bravo IN A 172.16.0.200
charlie IN A 192.168.0.2
delta IN A 192.168.0.3
www IN CNAME bravo
bd IN CNAME delta
```
### INTERNA INVERSA /var/cache/bind/db.0.168.192
```bash
$TTL 86400
@ IN SOA charlie.roberto.gonzalonazareno.org. root.roberto.gonzalonazareno.org. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
86400 ) ; Negative Cache TTL
;
@ IN NS charlie.roberto.gonzalonazareno.org.
$ORIGIN 0.168.192.in-addr.arpa.
1 IN PTR alfa.roberto.gonzalonazareno.org.
2 IN PTR charlie.roberto.gonzalonazareno.org.
3 IN PTR delta.roberto.gonzalonazareno.org.
```
### INTERNA INVERSA /var/cache/bind/db.16.172
```bash
$TTL 86400
@ IN SOA charlie.roberto.gonzalonazareno.org. root.roberto.gonzalonazareno.org. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
86400 ) ; Negative Cache TTL
;
@ IN NS charlie.roberto.gonzalonazareno.org.
$ORIGIN 16.172.in-addr.arpa.
1.0 IN PTR alfa.roberto.gonzalonazareno.org.
200.0 IN PTR bravo.roberto.gonzalonazareno.org.
```
### DMZ /var/cache/bind/db.dmz.roberto.gonzalonazareno.org
```bash
$TTL 86400
@ IN SOA charlie.roberto.gonzalonazareno.org. root.roberto.gonzalonazareno.org. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
86400 ) ; Negative Cache TTL
;
@ IN NS charlie.roberto.gonzalonazareno.org.
$ORIGIN roberto.gonzalonazareno.org.
alfa IN A 172.16.0.1
bravo IN A 172.16.0.200
charlie IN A 192.168.0.2
delta IN A 192.168.0.3
www IN CNAME bravo
bd IN CNAME delta
```
### EXTERNA /var/cache/bind/db.externa.roberto.gonzalonazareno.org
```bash
$TTL 86400
@ IN SOA alfa.roberto.gonzalonazareno.org. root.roberto.gonzalonazareno.org. (
1 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
86400 ) ; Negative Cache TTL
;
@ IN NS alfa.roberto.gonzalonazareno.org.
$ORIGIN roberto.gonzalonazareno.org.
alfa IN A 172.22.200.218
www IN CNAME alfa
```
## Configuración de los servidores web
```bash
<VirtualHost *:80>
ServerName www.roberto.gonzalonazareno.org
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<FilesMatch "\.php$">
SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://127.0.0.1/"
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
</VirtualHost>
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

@ -0,0 +1,177 @@
---
title: "Resolución de problemas de
tablas mutantes"
date: 2022-12-19T00:51:41+01:00
draft: false
image: featured.png
categories:
- documentación
- Administración de Bases de Datos
tags:
- tablas mutantes
- Oracle
- PL/SQL
---
El enunciado a resolver y que contiene una tabla mutante es el siguiente:
**6 - Realiza los módulos de programación necesarios para evitar que un catador puntue más de tres aspectos de una misma versión de un experimento.**
En este caso, el trigger principal sería sobre la tabla puntuaciones, y dentro, para comprobar que se cumple la condición de que un catador no puntúa más de 3 aspectos, se tendría que hacer una consulta a la misma tabla puntuaciones, que en ese caso estaría mutando. Para resolver el problema vamos a realizar los siguientes pasos:
1. Leer bien los requisitos del problema e identificar la
información de la tabla que debo guardar en variables
persistentes.
2. Crear el paquete declarando los tipos de datos y las variables
necesarias para guardar dicha información.
3. Hacer un trigger before por sentencia que rellene dichas
variables consultando la tabla mutante.
4. Hacer un trigger before por fila que compruebe si el registro
que se está manejando cumple la condición especificada
consultando las variables persistentes.
## Leer bien los requisitos del problema e identificar la información de la tabla que debo guardar en variables persistentes
El contenido de la tabla de puntuaciones es el siguiente:
![Tabla puntuaciones](https://i.imgur.com/wMxNzMj.png)
En este caso, tendríamos que almacenar en variables persistentes los datos de la consulta, que en este caso son los siguientes campos:
* NIFCatador
* CodigoAspecto
* CodigoExperimento
* CodigoVersion
## Crear el paquete declarando los tipos de datos y las variables necesarias para guardar dicha información
```sql
CREATE OR REPLACE PACKAGE ControlPuntuaciones
AS
TYPE tRegistroTablaPuntuaciones IS RECORD --defino el tipo de datos registro
(
NIFCatador Puntuaciones.NIFCatador%TYPE,
CodigoAspecto Puntuaciones.CodigoAspecto%TYPE,
CodigoExperimento Puntuaciones.CodigoExperimento%TYPE,
CodigoVersion Puntuaciones.CodigoVersion%TYPE
);
TYPE tTablasPuntuaciones IS TABLE OF tRegistroTablaPuntuaciones -- defino el tipo de datos tabla
INDEX BY BINARY_INTEGER;
PuntuacionesCatador tTablasPuntuaciones;
-- declaro una variable del tipo tabla antes creado
END ControlPuntuaciones;
/
```
## Hacer un trigger before por sentencia que rellene dichas variables consultando la tabla mutante
```sql
CREATE OR REPLACE TRIGGER RELLENARPUNTUACIONES
BEFORE INSERT OR UPDATE ON Puntuaciones
FOR EACH ROW
DECLARE
CURSOR c_puntuaciones IS SELECT NIFCatador,CodigoAspecto,CodigoExperimento,CodigoVersion
FROM Puntuaciones;
INDICE NUMBER:=0;
indice_u number;
BEGIN
-- vacio el contenido de la tabla
ControlPuntuaciones.PuntuacionesCatador.DELETE;
-- relleno la tabla de puntuaciones los datos que me interesan
FOR v_puntuacion IN c_puntuaciones LOOP
ControlPuntuaciones.PuntuacionesCatador(INDICE).NIFCatador := v_puntuacion.NIFCatador;
ControlPuntuaciones.PuntuacionesCatador(INDICE).CodigoAspecto := v_puntuacion.CodigoAspecto;
ControlPuntuaciones.PuntuacionesCatador(INDICE).CodigoExperimento := v_puntuacion.CodigoExperimento;
ControlPuntuaciones.PuntuacionesCatador(INDICE).CodigoVersion := v_puntuacion.CodigoVersion;
INDICE := INDICE + 1;
END LOOP;
if inserting then
indice_u := ControlPuntuaciones.PuntuacionesCatador.LAST + 1;
ControlPuntuaciones.PuntuacionesCatador(indice_u).NIFCatador := :NEW.NIFCatador;
ControlPuntuaciones.PuntuacionesCatador(indice_u).CodigoAspecto := :NEW.CodigoAspecto;
ControlPuntuaciones.PuntuacionesCatador(indice_u).CodigoExperimento := :NEW.CodigoExperimento;
ControlPuntuaciones.PuntuacionesCatador(indice_u).CodigoVersion := :NEW.CodigoVersion;
end if;
END RELLENARPUNTUACIONES;
/
```
## Hacer un trigger before por fila que compruebe si el registro que se está manejando cumple la condición especificada consultando las variables persistentes
```sql
CREATE OR REPLACE TRIGGER ControlarPuntuaciones
BEFORE INSERT OR UPDATE ON Puntuaciones
FOR EACH ROW
DECLARE
BEGIN
-- compruebo que el catador no haya puntuado más de 3 aspectos
IF (NumeroPuntuacionesCatador(:NEW.NIFCatador,:NEW.CodigoExperimento,:NEW.CodigoVersion) > 3) THEN
RAISE_APPLICATION_ERROR(-20001,'El catador no puede puntuar mas de 3 aspectos');
end if;
END;
/
```
Voy a crear una funcion para comprobar el numero de puntuaciones que tiene un catador en una versión de un experimento:
```sql
CREATE OR REPLACE FUNCTION NumeroPuntuacionesCatador
( p_NIFCatador Puntuaciones.NIFCatador%TYPE, p_CodigoExperimento Puntuaciones.CodigoExperimento%TYPE, p_CodigoVersion Puntuaciones.CodigoVersion%TYPE)
RETURN NUMBER
IS
v_NumeroPuntuaciones NUMBER:= 1;
v_cantidad NUMBER;
BEGIN
for i in ControlPuntuaciones.PuntuacionesCatador.FIRST..ControlPuntuaciones.PuntuacionesCatador.LAST
LOOP
if (ControlPuntuaciones.PuntuacionesCatador(i).NIFCatador = p_NIFCatador) and (ControlPuntuaciones.PuntuacionesCatador(i).CodigoExperimento = p_CodigoExperimento) and (ControlPuntuaciones.PuntuacionesCatador(i).CodigoVersion = p_CodigoVersion) then
v_NumeroPuntuaciones := v_NumeroPuntuaciones + 1;
end if;
END LOOP;
return v_NumeroPuntuaciones;
end;
/
--- prueba
create or replace procedure prueba
is
numero number;
begin
numero:=NumeroPuntuacionesCatador('14425879A','A0003-A','0.0.2');
dbms_output.put_line(numero);
end;
/
insert into puntuaciones values('14425879A','0004','A0003-A','0.0.2',7.5);
create or replace procedure imprimirtabla
is
begin
for i in ControlPuntuaciones.PuntuacionesCatador.FIRST..ControlPuntuaciones.PuntuacionesCatador.LAST
LOOP
dbms_output.put_line('Registro numero '|| i);
dbms_output.put_line('NIFCatador: '|| ControlPuntuaciones.PuntuacionesCatador(i).NIFCatador);
dbms_output.put_line('CodigoAspecto: '|| ControlPuntuaciones.PuntuacionesCatador(i).CodigoAspecto);
dbms_output.put_line('CodigoExperimento: '|| ControlPuntuaciones.PuntuacionesCatador(i).CodigoExperimento);
dbms_output.put_line('CodigoVersion: '|| ControlPuntuaciones.PuntuacionesCatador(i).CodigoVersion);
end loop;
end;
/
```
```sql
insert into puntuaciones values('14425879A','0004','A0003-A','0.0.2',7.5);
insert into puntuaciones values('14425879A','0005','A0003-A','0.0.2',7.5);
insert into puntuaciones values('14425879A','0006','A0003-A','0.0.2',7.5);
insert into puntuaciones values('14425879A','0007','A0003-A','0.0.2',7.5);
select * from puntuaciones where nifcatador='14425879A' and codigoexperimento='A0003-A' and codigoversion='0.0.2';
insert into puntuaciones values('14425879A','0005','A0003-A','0.0.1',7.5);
```

Before

Width:  |  Height:  |  Size: 304 KiB

After

Width:  |  Height:  |  Size: 304 KiB

Before

Width:  |  Height:  |  Size: 233 KiB

After

Width:  |  Height:  |  Size: 233 KiB

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Before

Width:  |  Height:  |  Size: 257 KiB

After

Width:  |  Height:  |  Size: 257 KiB

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Before

Width:  |  Height:  |  Size: 125 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Before

Width:  |  Height:  |  Size: 516 KiB

After

Width:  |  Height:  |  Size: 516 KiB

Before

Width:  |  Height:  |  Size: 109 KiB

After

Width:  |  Height:  |  Size: 109 KiB

Before

Width:  |  Height:  |  Size: 546 KiB

After

Width:  |  Height:  |  Size: 546 KiB

Before

Width:  |  Height:  |  Size: 407 KiB

After

Width:  |  Height:  |  Size: 407 KiB

Before

Width:  |  Height:  |  Size: 459 KiB

After

Width:  |  Height:  |  Size: 459 KiB

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 273 KiB

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

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

Loading…
Cancel
Save