Múltiples idiomas en django

No hay momento mas dulce en el desarrollo de un programa el ver que va tomando solidez y que puedas implantar detallitos interesantes en la generación de pdf, navegar por el programa que va a los sitios que tiene que ir, etc. Hoy vamos a hablar de una de estas otras cosas que señalan el avanzado estado de nuestro programa, la internacionalización, el disponer la página en varios idiomas. Vamos a contarlo!

Primero de todo recomiendo tener a mano la documentación de django y éste otro artículo de Alex Dzul al que le he copiado el título y la metedología.

Para resumir, lo que tendremos que hacer será configurar el settings.py, preparar y traducir la interfaz y finalmente generar los ficheros .po. En la documentación te habla primero de la generación de los ficheros de traducción y después desarrollar la traducción en la interfaz (templates), luego contaré porqué es mejor hacerlo al revés.

Así que empezamos

Primero modificaremos el fichero settings.py de nuestro proyecto

(venv) laura@melatonina:~/dev/colibri$ vi colibri/settings.py 
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

[...]

MIDDLEWARE_CLASSES = (
    # ...
    'django.middleware.locale.LocaleMiddleware',
    # ...
)

[...]

# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
# https://www.pythoniza.me/multiples-idiomas-en-django/

LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Europe/Madrid'
USE_I18N = True
USE_L10N = True
USE_TZ = True

from django.utils.translation import ugettext_lazy as _
LANGUAGES = (
    ('en', _('English')),
    ('es', _('Spanish')),
    ('ca', _('Catalan')),
)

# Definimos la ruta de los archivos de idiomas
LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
)

# Definimos el procesador de contexto para i18n
#from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS 

Generar pdf con pie/cabecera con python, pdfkit y wkhtmltopdf

Ya llevo varios meses peleándome con pdfkit, al tener que atender otras partes de mi programa lo he ido dejando hasta que realmente he tenido la necesidad de ponerme a hacer funcionar correctamente pdfkit. La documentación que he encontrado por ahí ha sido un poco confusa, además de que estaba teniendo problemas con la versión del wkhtmltopdf y me estaba volviendo loca!

Ahora mismo tengo la necesidad de crear un pdf con sus márgenes, cabecera, pie y numero de página, además no quiero que salga la cabecera y pie de página en la primera página.

Primero de todo tendremos que tener en cuenta que pdfkit hace uso del programa wkhtmltopdf, que está en los repositorios de debian, pero me encuentro que éste no está compilado con qt, como tal al usar según que opciones de la configuración de wkhtmltopdf me soltaba un error similar a éste:

The switch --enable-internal-links, is not support using unpatched qt, and will be ignored.
The switch --footer-center, is not support using unpatched qt, and will be ignored.
The switch --header-html, is not support using unpatched qt, and will be ignored.
The switch --footer-html, is not support using unpatched qt, and will be ignored.

Para ello lo que haremos será primero de todo desinstalar wkhtmlpdf instalado en el sistema e instalar el .deb que nos ofrecen en la página del proyecto de wkhtmltopdf.

# apt remove --purge wkhtmltox
# wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb
# dpkg -i wkhtmltox_0.12.6-1.buster_amd64.deb

Para seguir preparando el sistema, vamos a instalar la librería de …

Proxmox: iptables nat vmbr0 y vmbr11

En éste caso la configuración que tenemos del servidor tenemos como siempre en vmbr0 una IP de guifi.net (que trato como ip local) y debido a que el numero de IPs públicas que tengo es limitada, tengo otro bridge vmbr11 con una red interna para comunicar las aplicaciones que sirven HTTP, luego tengo un contenedor con nginx y acceso a las 3 redes, la de guifi, la pública y la interna de las aplicaciones.

Para que las máquinas que están en la red de guifi y la de las aplicaciones puedan acceder a internet tendremos que configurar el NAT, para ello haremos lo siguiente:

En /etc/network/interfaces

root@wezen1A:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback

iface eth0 inet manual

auto vmbr0
iface vmbr0 inet static
	address 10.90.234.166
	netmask 255.255.255.224
	gateway 10.90.234.161
	bridge_ports eth0
	bridge_stp off
	bridge_fd 0
	post-up echo 1 /proc/sys/net/ipv4/ip_forward

iface eth1 inet manual

auto vmbr1
iface vmbr1 inet static
        address 192.168.10.1
        netmask 255.255.255.0
        bridge_ports eth1     
        bridge_stp off
        bridge_fd 0

auto vmbr138
iface vmbr138 inet manual
        bridge_ports eth0.138
        bridge_stp off
        bridge_fd 0

auto vmbr11
iface vmbr11 inet static
        address 192.168.100.1
        netmask 255.255.255.0
        bridge_ports eth0.11
        bridge_stp off
        bridge_fd 0

La vmbr1 la tengo destinada a ceph, para que las maquinas compartan el disco ahí, además con su switch a parte! :) la vmbr138 es la que uso para las IPs públicas, en ésta red no vamos a aplicar NAT porqué las máquinas que estén en ésta red tendrán como gateway la IP del router. En vmbr0 ponemos en post-up el …

Proxmox: habilitar virtualización anidada (nesting virtualization)

Uno de los problemas que me estoy encontrando últimamente es que los contenedores lxc que instalo con debian 10 no arrancan los servicios porque tengo que reconfigurar systemd para decirle que el PrivateTmp es false, por ejemplo para poder levantar apache2 tendría que hacer ésto

Job for apache2.service failed because the control process exited with error code.
See "systemctl status apache2.service" and "journalctl -xe" for details.
invoke-rc.d: initscript apache2, action "start" failed.
* apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Wed 2020-07-01 16:35:29 UTC; 9ms ago
     Docs: https://httpd.apache.org/docs/2.4/
  Process: 11730 ExecStart=/usr/sbin/apachectl start (code=exited, status=226/NAMESPACE)

Jul 01 16:35:29 wordpress systemd[1]: Starting The Apache HTTP Server...
Jul 01 16:35:29 wordpress systemd[11730]: apache2.service: Failed to set up mount namespacing: Permission denied
Jul 01 16:35:29 wordpress systemd[11730]: apache2.service: Failed at step NAMESPACE spawning /usr/sbin/apachectl: Permission denied
Jul 01 16:35:29 wordpress systemd[1]: apache2.service: Control process exited, code=exited, status=226/NAMESPACE
Jul 01 16:35:29 wordpress systemd[1]: apache2.service: Failed with result 'exit-code'.
Jul 01 16:35:29 wordpress systemd[1]: Failed to start The Apache HTTP Server.

# vi /lib/systemd/system/apache2.service
PrivateTmp=false
:wq
# systemctl daemon-reload
# systemctl start apache2.service

Pero me encuentro el mismo problema con otros servicios que instalo.

Por lo que entiendo systemd crea como una especie de “entorno virtual” para cada uno de los servicios y para que funcione correctamente, leyendo documentación veo que la solución es habilitar la virtualización anidada.

Así que en la documentación de proxmox encontramos ésta página que nos dice como hacerlo.

Tendremos …

Instalar entorno de producción de python

Una vez hemos desarrollado una aplicación con django nos interesará ponerla en producción. La forma correcta de hacerlo es usando uwsgi + nginx. Así que vamos a ello.

Mi aplicación corre sobre postgresql así que instalaremos los siguientes paquetes

# apt -y install nginx uwsgi uwsgi-plugin-python3 postgresql python3-psycopg2 libpq-dev git virtualenv memcached

Creamos el usuario y la base de datos postgresql

# su - postgres
$ createuser colibri_user
$ createdb -O colibri_user colibri_db
$ psql colibri_db
colibri_db=# alter user colibri_user with encrypted password 'XXXXXXXX';
colibri_db=# grant all privileges on database colibri_db to colibri_user;

Ahora clonamos el código del programa en /var/www

# cd /var/www/
# git clone git@git.capa8.net:blackhold/colibri.git

Creo el entorno virtual

# cd colibri
# virtualenv -p python3 venv

Entro en el entorno virtual y ejecuto los comandos necesarios para iniciar la aplicación

# source venv/bin/activate
# pip install -r requirements.txt
# ./clean.sh
# python manage.py runserver 0.0.0.0:5001

Ahora configuramos uwsgi para que apunte donde está nuestra aplicación de django

# cd /etc/uwsgi/apps-available
# vi colibri.ini
[uwsgi]
master = true
processes = 10
socket = /tmp/uwsgi-colibri.sock
uid = www-data
gid = www-data

;# with appropriate permissions - *may* be needed
;chmod-socket    = 664

chdir = /var/www/colibri
module = colibri.wsgi
home = /var/www/colibri/venv/
vacuum = true
env = DJANGO_SETTINGS_MODULE=colibri.settings
safe-pidfile = /tmp/uwsgi-colibri.pid
;harakiri = 20 # respawn processes taking more than 20 seconds
;limit-as = 128 # limit the project to 128 MB
max-requests = 5000
daemonize = /var/log/uwsgi/colibri.log
;callable = application
plugin = python37

Guardamos y lo activamos en …

Pyocclient: Apuntes

Abro éste post para ampliar un poco como se usa pyoocclient, una librería de python para gestionar un nextcloud. En éste post voy a mostrar como he solucionado el tema de crear directorios, subir ficheros, compartir ficheros, descargar un fichero (binario) y eliminar ficheros, pero la librería permite incluso hacer gestión de usuarios y algunas cosas mas, realmente da para seguir jugando :) En página podéis ver el código de la librería.…

GlusterFS

GlusterFS es un gestor de ficheros en red. Básicamente lo que permite es replicar unos mismos ficheros en varios servidores, para luego con los clientes de glusterfs conectar a alguno de ellos y definir otro de backup en el caso de que se caiga el primero. Con éste sistema tenemos redundancia de los datos.

La recomendación es usar 3 nodos servidores de gluster, en mi caso, ahora mismo no dispongo del tercero, y lo añadiré mas tarde.

Vamos a trabajar con 3 nodos, Node1A, Node1B y Node2A, los dos primeros serán los servidores que tendrán el disco duro que queremos compartir en red, y el último sólo va a actuar como cliente.…

proxmox 6 + ceph

Por fin otro logro mas que me había dado guerra durante muchas horas, el motivo un ceph roto al que de momento he preferido migrar los datos a otro sitio y ya con mas calma intentaremos recuperarlo (ya vendrá otro post otro día sobre éste tema).

En motivo del ceph roto he aprovechado para reinstalar la infraestructura de proxmox entera sobre proxmox6 (debian10).

Partimos de 5 nodos unidos en el cluster (pvecm add ipmaster), sólo vamos a instalar ceph en 3 de ellos.

- node1A - 172.31.0.1 (ceph)
- node1B - 172.31.0.2
- node1C - 172.31.0.3 (ceph)
- node1D - 172.31.0.4 (ceph)
- node2D - 172.31.0.8

El nodo maestro del cluster es “node1D”, y para ver que ésto no implica nada a la hora de configurar ceph y también porque romper el 1D era una cosa que no me podía permitir… vamos a empezar por “node1A”.

Para ello vamos a la interfaz web de proxmox e instalamos ceph:…

Nextcloud sobre nginx y postgreSQL + fulltextsearch + paquetes ofimáticos collabora o onlyoffice-ds sobre docker

Hoy les traigo un manual de éstos tochos o al menos para llegar hasta aquí ya que hay mucha documentación pero ninguna que lo englobe todo, así que os voy a mostrar mi experiencia y los pasos seguidos.

Primero de todo, la política ha sido de instalar cada servicio en un contenedor o máquina virtual. La instalación de nextcloud va a estar instalada sobre un contenedor lxc y los paquetes ofimáticos, que los vamos a instalar usando docker, sobre las máquinas virtuales kvm. El motivo es que docker no funciona muy bien sobre contenedores lxc.

La otra cosa que tenemos que tener en cuenta, es que para hacer funcionar los paquetes ofimáticos, vamos a usar proxys de nginx, las máquinas van a requerir que se vean correctamente entre ellas y el usuario a las maquinas. Ésto lo comento porque la idea inicial era montar todo el sistema sobre un mismo servidor compartiendo la misma IP y repartir en el host que alberga las maquinas virtuales con iptables a los puertos correspondientes. Ésto me ha dado problemas, así que la mejor opción es servicios preparados.
En éste post me hubiese gustado documentar elasticsearch para poder buscar entre los ficheros, pero aún lo tengo a medio instalar y no he conseguido aún la comunicación. Espero que en unos días pueda publicar otro post en éste mismo blog de como hacer la integración nextcloud-fulltextsearch-elasticsearch.

Así que vamos a empezar! :)

Nextcloud
Partimos de un contenedor lxc, ésto quiere decir que el procedimiento se …

Servidor ldap

ldap es un sistema de autenticación que nos puede valer para centralizar la autenticación de los usuarios. Una vez creada ésta base de datos podemos llamar a los programas que requieran autenticación contactar con ésta base de datos centralizada.

Partimos como casi siempre con una Debian recién instalada y ahí instalamos slapd que es el servicio de ldap y ldap-utils que nos va a permitir gestionar la base de datos ldap.

# apt -y install slapd ldap-utils 

Durante la instalación nos va a pedir el password para el usuario admin (cn=admin,dc=capa8,dc=net).

En algunos manuales hacen referencia a tocar los ficheros de configuración. Dicha acción no es recomendable, para ello, lo recomendable es usar browsers de ldap como jxplorer con el que entraremos mas adelante o con las herramientas que trae ldap-utils.

De momento, para verificar que el servidor está funcionando, en el mismo servidor donde hemos instalado ldap, vamos a ejecutar el comando slapcat, que nos muestra el contenido de la base de datos ldap

# slapcat

Con el siguiente comando vamos a poder ver las entradas disponibles

# ldapsearch -x -h localhost

A continuación para configurar nuestro dominio vamos a reconfigurar slapd

# dpkg-reconfigure -plow slapd 
Omit ldap configuration: NO
DNS domain name: capa8.net
Organization name: Capa8
Administrator Password: password
Database backend to use: MDB
Do you want database to be removed when slapd is purged? NO
Move old database?: YES

Creación y configuración de Usuario, Grupos y U. Organizativas en LDAP.
Ahora vamos a crear todos los objetos …