"Después del juego es antes del juego"
Sepp Herberger

martes, 10 de enero de 2017

Listado jerárquico de dispositivos PCI

Ultimamente los infolabs me han dado mucha guerra, tras los problemas con la tarjeta nvidia y el Secure Boot, la última ha sido que la tarjeta de red de la placa (identificada como 00:1f.6 Ethernet controller: Intel Corporation Ethernet Connection (2) I219-LM - rev 31, con id 8086:15b7) no servía para hacer NAT a los 15 PC de los alumnos: tan pronto como había un poco de tráfico la conexión se iba al carajo y se bloqueaba el PC del profesor y los escritorios de los alumnos.

Al final he optado por ignorarla (el contrato de infolabs dice que la empresa adjudicataria debe asegurar compatibilidad del hardware durante 5 años, pero no lo voy ni a intentar) y pinchar otra tarjeta para hacer NAT. Bueno, pues ya parecía que la cosa estaba estable cuando veo que me estaba saliendo compulsivamente este error en el syslog:
Jan  9 10:29:52 A07-PRO kernel: [  140.353087] pcieport 0000:00:1c.0: AER: Corrected error received: id=00e0
Seguramente ya salía antes, pero con los errores de la tarjeta de red me pasaban desapercibidos. El error aparece en el dispositivo 0000:00:1c.0, ¿que es eso?. Veamos:
# lspci | grep 1c.0
00:1c.0 PCI bridge: Intel Corporation Sunrise Point-H PCI Express Root Port #6 (rev f1)
Bueno, es un conector PCI Express, pero no creo que el bus esté dando problemas en si mismo. El problema lo dará el dispositivo que está enchufado a dicho puerto PCI. ¿Se puede averiguar que hay conectado ahí desde terminal?... pues claro:
# lspci -vt
-[0000:00]-+-00.0  Intel Corporation Sky Lake Host Bridge/DRAM Registers
           +-01.0-[01]----00.0  NVIDIA Corporation GK208 [GeForce GT 730]
           +-02.0  Intel Corporation Sky Lake Integrated Graphics
           +-14.0  Intel Corporation Sunrise Point-H USB 3.0 xHCI Controller
           +-14.2  Intel Corporation Sunrise Point-H Thermal subsystem
           +-16.0  Intel Corporation Sunrise Point-H CSME HECI #1
           +-16.3  Intel Corporation Sunrise Point-H KT Redirection
           +-17.0  Intel Corporation Sunrise Point-H SATA controller [AHCI mode]
           +-1c.0-[02]----00.0  Intel Corporation Wireless 7265
           +-1c.6-[03]----00.0  Intel Corporation 82574L Gigabit Network Connection
           +-1d.0-[04]----00.0  Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
           +-1f.0  Intel Corporation Sunrise Point-H LPC Controller
           +-1f.2  Intel Corporation Sunrise Point-H PMC
           +-1f.3  Intel Corporation Sunrise Point-H HD Audio
           +-1f.4  Intel Corporation Sunrise Point-H SMBus
           \-1f.6  Intel Corporation Ethernet Connection (2) I219-LM

Como podemos ver, este comando "lspci -vt" nos da un punto de vista jerárquico de los dispositivos y así podemos ver que en dicho puerto está conectado "Intel Corporation Wireless 7265", una tarjeta inalámbrica PCI que traen los infolab y que no vale para un carajo. Buscando en Internet no he encontrado una causa clara del error, así que he optado por anular ese puerto PCI. Para ello metemos en /etc/rc.local la línea:
echo 1 > "/sys/bus/pci/devices/0000\:00\:1c.0/remove"
Antes del exit final. Esto hace que el bus PCI 1c.0 desaparezca de la lista de dispositivos en el arranque, de tal forma que la tarjeta Wifi se vuelve invisible (ni siquiera aparece el dispositivo wlan0 ni se carga módulo) y el error en el syslog desaparece. Es el equivalente lógico a abrir el PC y arrancarle la tarjeta de sus malditas entrañas.

No tenía mucho sentido tener ese error metiendo ruido en el syslog producido por algo que no voy a usar jamás, así que otro problema resuelto y a otra cosa, mariposa.

viernes, 6 de enero de 2017

Android en el PC de sobremesa (Parte I)

Debido a que cada vez es mas fácil encontrar aplicaciones interesantes educativas para la ESO y los Ciclos Formativos que solo corren en dispositivos Android (por ejemplo, aplicaciones de maquillaje para los Ciclos de Peluquería y Estética), he estado intentando hacer funcionar, con vistas a probar luego en portátiles e infolabs, el sistema Android en los PC de sobremesa con prometedores resultados.

Para las pruebas he usado un PC clónico con procesador Dual-Core E5200-2.50GHz y 4Gb de RAM y con Mint 18 instalado. El sistema usado para la instalación es una maravilla llamada Remix OS, una mejora de Android-x86, el port de Android (que normalmente corre sobre ARM) a dispositivos x86.

Los pasos son:

  1. Empezamos por descargar el fichero de instalación. Como mi hardware es un poco obsoleto, me descargo la versión de 32bits.
  2. La descarga es un archivo .zip que descomprimimos dando lugar, entre otras cosas, a un fichero .iso que también procederemos a descomprimir con:
    # 7z x Remix_OS_for_PC_Android_M_32bit_B2016101201.iso 
    
  3. .
  4. Ahora creamos un directorio donde poner todo y copiamos los ficheros necesarios:
    # mkdir /remix
    # cp initrd.img kernel ramdisk.img system.sfs /remix
    # mkdir /remix/data
    
  5. Añadimos una entrada para arrancar Remix al Grub y lo regeneramos:
    # cat /etc/grub.d/40_custom 
    #!/bin/sh
    exec tail -n +3 $0
    # This file provides an easy way to add custom menu entries.  Simply type the
    # menu entries you want to add after this comment.  Be careful not to change
    # the 'exec tail' line above.
    
    menuentry "Remix OS" --class android-x86 {
       insmod gzio
       insmod part_msdos
       insmod ext2
       search --file --no-floppy --set=root /remix/system.sfs
       linux /remix/kernel root=/dev/ram0 androidboot.hardware=remix_x86 androidboot.selinux=permissive nouveau.modeset=1 i915.modeset=0 SRC=/remix DATA= CREATE_DATA_IMG=1 
       initrd /remix/initrd.img
    }
    # update-grub2
    

Y con esto reiniciamos y en el Grub debe aparecer la opción "Remix OS".



Si lo seleccionamos y está todo bien configurado, con un poco de paciencia viendo la pantalla:


Tras una espera inicial un poco desesperante y quizá algún reinicio tendremos el Android en nuestro PC, pero vamos a comentar y aclarar varias cosas antes:

  • En mi 40_custom he puesto "androidboot.hardware=remix_x86" porque tengo la versión de 32 bits, si fuera la versión de 64 bit pondria remix_x86_64.
  • Podemos descomprimir otra versión en otra ruta, por ejemplo /remix_test/ y cambiando los directorios en el fichero de Grub jugar con varias versiones de Android.
  • He tenido problemas con la tarjeta gráfica. En mi caso tenia una Intel G33 en placa y una Nvidia GeForce 210 en PCI express. Al arrancar me salía una extraña splash screen con trozos de Minecraft pixelados (prueba de que en la memoria siempre algo queda después de que mi muchachada eche unas partidas) y, perfectamente visible, la grafía "Friki". No me lo tomaré como algo personal.
  • La solución encontrada ha sido desactivar la tarjeta Intel de la placa en la BIOS y poner los parámetros "nouveau.modeset=1 i915.modeset=0" para quedar claro que driver carga y configura la pantalla.
  • Los primeros arranques son muuuuuy lentos, ya que tiene que crear un sistema de ficheros loop en /remix y hacer varias inicializaciones y configuraciones, pero al final aparece el escritorio.
  • La conexión wifi puede funcionar o no en función de si la tarjeta está soportada. Mi USB-Wifi Realtek RTL8192SU no lo está, pero poniendo una TP-Link TL-WN821N no he tenido problema. La conexión cableada si ha funcionado.
  • Si queremos poder usar Google Play (no es mi caso, quiero descargar e instalar las aplicaciones de forma controlada) nada mas entrar es conveniente dar al icono "Play Activator" del escritorio o del menú de inicio, dejar que actúe e inmediatamente después reiniciar el sistema. Tras un nuevo arranque se supone que Play está operativo (Nota: la app Roblox no viene por defecto, la he instalado a petición de mis zagales y para probar una aplicación con 3D)
  • En mi caso, tras el primer arranque completo y conexión a red ha detectado una actualización del sistema (vamos, una OTA). La he descargado y dicho que actualice y, tras otro largo rato de espera, ha acabado bien.

Y nada más. En principio, con copiar /remix y /etc/grub.d/40_custom a otra máquina será suficiente para poder lanzar allí Android, realizando pequeños ajustes en función del hardware que nos toque.

Seguiremos informando de los avances.

miércoles, 4 de enero de 2017

Más Kodi, por favor

En estos días libres me he puesto a configurar el Kodi que tengo en el AndroidBox que me agencié en Aliexpress, ya que quería comprobar si el visionado en streaming funciona tan bien como dicen en los foros. Hasta ahora lo usaba para ver cosas descargadas en el servidor DLNA de casa con mldonkey (es un viejo router con OpenWrt y un disco externo que gasta menos que un mechero) pero nunca lo usaba para nada online. Esta entrada la dejo a modo de recordatorio por si tuviera que hacerlo de nuevo.

Antes de nada, recomendar Kodi. Es una prueba en vivo de que se puede hacer software libre, gratuito y de calidad insuperable. Si alguna vez os piden un ejemplo de todo lo anterior, decid "Kodi" y se acabó la discusión.

Bueno. Lo primero es instalar los plugins que permiten ver contenido online. En mi caso ya venían instalados en el AndroidBox. Los plugins de vídeo son:

  • Exodus: para contenidos preferentemente en inglés. Tiene un buscador muy potente que te da acceso a decenas de servidores con los contenidos, en resoluciones tanto de 1080 como de 720. Se instala según estos pasos.
  • Pelisalacarta: para contenidos en español. No tiene tanto como Exodus y muchas veces los servidores están caídos o dan fallos de conexión, pero luego comentamos un servidor que a mi normalmente me funciona y no da problemas. Estas son las instrucciones de instalación. Ojo: aparecen 2 plugins de pelisalacarta, uno con el nombre "pelisalacarta UI". Este último es un skin del original con un interface mas bonito.

Una vez descargados e instalados vemos que Exodus funciona a la primera, pero tenemos el problema de que al tener casi todo el contenido en inglés y si tienes, como tengo yo, nulo oído para el idioma de la Pérfida Albión no queda otra que poner los subtítulos. Para ello instalamos los siguientes plugins:

  • Opensubtitles: es posiblemente el repositorio mas grande de la red. Aquí tenemos como hacerlo y como configurar correctamente los idiomas de búsqueda de subtítulos (yo pongo primero Español y como secundario Inglés). Tambien es impepinable darnos de alta en su página y configurar las credenciales (usuario/contraseña) en la ventana de configuración del plugin.
  • Argenteam: un clásico de los subtítulos en español. Se configura con estas instrucciones.
  • Subtitles.es: otra opción. Instrucciones.
  • Subdivx: está la usé mucho en el pasado, cuando descargábamos cosas con el emule o el Ares. No está mal configurarla y tenerla como reseva.

Realmente con OpenSubtitles tenemos casi todo resuelto, ya que además suele tener mucha variedad del mismo subtítulo con distintas temporizaciones, pero mejor que haya varias opciones de búsqueda donde elegir.

Otra cosa interesante es que al abrir un contenido se nos lance la búsqueda de sus subtítulos de forma automática. Eso viene muy bien si usamos preferentemente Exodus porque nos gusta ver cosas en su idioma original. Esa búsqueda automatizada se hace con el plugin Automatic Subtitles.

Por último, sobre pelisalacarta. Tiene infinidad de canales que funcionan regular, pero recomiendo usar el canal "pordede" por su fiabilidad. Primero debemos darnos de alta en su página y con esas credenciales configurar el canal en cuestión. Luego, en la búsqueda dentro de pelisalacarta no usaremos la búsqueda general (tarda mucho y nos da enlaces que en su mayoría fallan). Lo haremos por canales, seleccionando el canal pordede y realizando la búsqueda allí. Éxito garantizado.

Y puedo confirmar que todo va de maravilla, rápido y sin cortes. Entre esto y el Amazon Prime Video, gratuito para los yonkis de Amazon Premium como yo, vaya tupa de ver cosas atrasadas me estoy dando. Si Aute escribiese ahora la canción sería "Más Kodi, por favor".

Siguiente reto: usar el plugin popcorntime.

Hasta pronto, prometo que volveré con cosas serias.

sábado, 31 de diciembre de 2016

Hasta los uefis

Voy a echar un poco de bilis, ya que llevo varios meses teniendo encontronazos con este tema y tengo que escribir sobre ello. Antes de nada debo dejar constancia que no domino el asunto y que seguramente estoy equivocado y confundo conceptos, pero soy español (y cuñado) y eso me faculta para sentar cátedra, sepa o no.

Hace muchos años, cuando era mas bisoño me creía casi cualquier cosa que sonase chachi y bien. Por ejemplo, pensaba que el dinero de los bancos centrales estaba respaldado por oro y otros bienes tangibles en cajas fuertes rodeadas de guardias armados y que cuando se "emitía moneda" era porque se había se comprado oro para respaldar esa emisión y estaba en esta forma:



Juas, juas, era mas inocente que Bambi. El dinero se crea desde hace decenios con un spinner



Tras esta ida de olla recupero el hilo y, como decía, en esos años recuerdo haber leído un prometedor artículo sobre la nueva generación de BIOS que venía a mejorarnos las cosas sin que nadie la hubiese pedido, como tantas y tantas cosas que el capitalismo nos regala y luego nos cobra con intereses.

Era tremendo: unas BIOS amigables con entorno gráfico que nos permitrían conectarnos a Internet y navegar, ejecutar utilidades y realizar reparaciones (e instalaciones) del sistema operativo en un PC que lo tuviese dañado. Un sistema embebido que nos traería al futuro. Un futuro glorioso.

Bueno, como dice la Polla Records, hoy es el futuro. Esa BIOS se llamo EFI y luego UEFI. Repasemos rápido las prestaciones: soporta particiones GPT, admite drivers y aplicaciones ad-hoc para cargar y ejecutar desde la BIOS, tiene un en entorno modular, un gestor de arranque y un GUI manejable con ratón,.... Repasemos cada "avance":

  • Particiones GPT, adios al MBR. Ya podemos tener mas de 4 particiones por disco duro, ¡Gloria a Adonai!. Bueno, maticemos . Ya habia otros métodos usados en BIOS para tener mas de 4 particiones. Eso no dependía realmente de la BIOS, sino de la estructura de datos de 4 registros usada como tabla de particiones de tipo msdos en los 512 bytes del MBR (o mas si teníamos un gestor de arranque mas elaborado que el básico).
  • Un sistema para cargar drivers hechos especialmente para EFI y tener un entorno con red, sonido, rayos láser y conexión con la cafetera USB. Una vieja demanda de los usuarios: una BIOS con drivers para dispositivos complejos.
  • Podemos usar el ratón en un entorno gráfico chachi. Yo he visto varias BIOS de AMI manejadas con ratón en un modo gráfico algo vintage, pero mejor que no se corra la voz, que luego soy un aguafiestas.
  • Abundando en el entorno UEFI: la U significa "Universal", pero desde luego el GUI no es universal. Cada máquina y modelo tiene una UEFI con sus propios menús y hotkeys según la distribución aleatoria que escoge mediante dados el encargado del desarrollo.
  • Un gestor de arranque propio, vaya, debe ser que el Grub y la pléyade de gestores de arranque que hay no les parecia bastante.
  • También recuerdo que a mi me prometieron hace años que se podría conectar remotamente a la BIOS y reinstalar un sistema operativo dañado desde ella, pero que yo sepa eso solo lo he visto implementado en servidores con algo que, a diferencia de UEFI, si es útil y funciona bien: los sistemas de gestión out-of-band, como el ILO de HP y el equivalente de otras marcas, que llegan de verdad a donde EFI se quedó en promesa.
  • No solo eso, resulta que me comenta mi compañero Oscar que además se pude instalar un backdoor en el UEFI y comunicarnos con él desde el sistema operativo, de tal manera que se podrán escalar privilegios hasta ser usuario root. Como dicen en el artículo enlazado: "And, more importantly, once your kernel was loaded, BIOS was pretty much out of the picture"/"una vez el kernel se ha cargado, la BIOS está mas bonita fuera de escena".


Pero bueno, yo he venido aquí a hablar de mi libro, y realmente lo que me revienta de UEFI son las aplicaciones.La E de UEFI significa extensible, y yo entiendo que eso significa que se puede extender con aplicaciones. Veamos la lista de aplicaciones, ese prometedor "UEFI app store":


Todo lo que he podido encontrar son frikadas, ejemplos del nivel de un "Hello World" y cosas rarunas. Lo anuncio con el corazón encogido: nunca podremos navegar en Internet desde nuestra EFI.

Y ahora es el momento de contar de que va el post. Yo sé para que existe EFI, por que se ha implementado y por que perdurará: la respuesta es Secure Boot. Ese engendro concebido para impedir o dificultar al máximo la instalación de sistemas operativos que no sean de Microsoft. Estoy seguro de que UEFI existe, está concebida e impulsada para implementar Secure Boot. Todo lo demás es una cortina de humo que se puede implementar de forma mucho menos barroca desde un bootloader o con un sistema out-of-band.

Y Secure Boot no es un sistema para impedir que entre malware, no seamos niñatos. La mayoria de malware que veo se mueve en pendrives y se ejecuta con rol de usuario, buscando un sistema donde pueda escalar a administrador. ¿Que porcentaje del malware existente intenta modificar el arranque?. Por favor, que no estamos en los 80 con el virus Stoned. Todo es mentira. La única finalidad es hacer la puñeta y lo consiguen.

Hace un tiempo he perdido varias horas en un PC con una tarjeta gráfica nvidia que al cerrar sesión o intentar ir a consola quedaba el entorno gráfico "colgado", sin errores en los logs y el PC accesible por ssh, aunque las X eran imposibles de matar y un kill -9 era ignorado. Si en UEFI habilito Secure Boot eso no pasa. Si deshabilito Secure Boot y dejo el arranque Legacy, si pasa. ¿Que conexión hay entre Secure Boot y el comportamiento de una tarjeta nvidia?. Ni lo se ni me importa.

Me reafirmo: Secure Boot está concebido para hacer el mal y lo hace muy bien.

Feliz entrada de año.

miércoles, 21 de diciembre de 2016

Sobreescribir una regla puppet

Estaba escribiendo una regla puppet que necesitaba para instalar un paquete de mi compañero Esteban Navas de forma local y me he encontrado que ya hay otra regla puppet puesta por la Sección que choca con la mía:
package { "pkgsync": 
        ensure => latest 
}
Evidentemente, no puedo borrar la regla puppet de la Sección ya que su puppetmaster reina y tiraniza el mío, lo cual es lo correcto. Pero he descubierto que si puedo sobreescribirla/anularla ("override") para que ignore la suya y tenga en cuenta la mía, en una suerte de disidencia limitada. Es un concepto parecido al overriding de métodos en POO al definir una clase que hereda de otra.

Mi idea era poner esto:
package { "pkgsync" :
                  provider => dpkg,
                  ensure => latest,
                  source => "/var/cache/pkgsync_1.35-1_all.deb",
                  configfiles => replace,
}
Pero claro, me da un conflicto con lo anterior y el puppet peta a lo grande. En cambio si lo pongo con esta curiosa sintaxis:
Package  <|title == "pkgsync"|> {
                  provider => dpkg,
                  ensure => latest,
                  source => "/var/cache/pkgsync_1.35-1_all.deb",
                  configfiles => replace,
}
El puppet lo acepta, ignora lo de la Sección y coge mi regla. Estupendo.

Bueno nos vamos pero no sin compartir la noticia de la semana-mes-año-siglo: el EMDrive parece que funciona, según las pruebas que han hecho los chinos en su estación espacial. Es poco probable que sea cierto, pero como funcione me voy a dar un viaje a Marte, sin que me frían las neuronas como a Arnie, y una vez alli que me busque Rita:





Descarga directa de linea de comandos desde Google Drive

Últimamente me veo en la tesitura de descargar ficheros bastante grandes (vídeos e imágenes de clonación, por ejemplo) que me pasan vía enlaces de Google Drive. Aunque la descarga se puede hacer desde el navegador a veces esto no es lo mas cómodo, ya que:
  • Por algún motivo inexplicable, estas descargas desde el navegador son mas delicadas y no es extraño que fallen. Concretamente, cuando van al 95%.
  • Si el destino del fichero es otro PC (por ejemplo, un servidor sin entorno gráfico y navegador) luego hay que copiar el fichero desde nuestro PC al destinatario.
  • Somos sysadmin, si algo se puede hacer por consola es una pérdida de tiempo andar moviendo el ratón.
Por tanto partimos de un enlace a un fichero almacenado de Google Drive (y compartido de forma pública) como éste:
https://drive.google.com/open?id=0B8np4HndYC-lQi0wamstRHF1S3M
Y queremos descargarlo como se descargan ficheros con wget o curl. Evidentemente, usar wget o curl con este enlace no funciona. Necesitamos otra herramienta llamada gdrive. En su página viene un completo manual ya que es una herramienta muy potente para interactuar de muchas formas con Google Drive desde línea de comandos, aunque a mi solo me interesa de momento descargar ficheros.

Lo primero es bajar el programa, que es un ejecutable tal cual sin empaquetar. Las versiones para Linux usables por nosotros son:
  • gdrive-linux-x64 2.1.0 Linux 64-bit 4fd8391b300cac45963e53da44dcfe68da08d843
  • gdrive-linux-386 2.1.0 Linux 32-bit de9f49565fc62552fe862f08f84694ab4653adc2
Bajamos la que corresponda según nuestra arquitectura, la hacemos ejecutable con chmod +x y la ponemos en /usr/local/bin o ruta similar. Una vez descargado debemos lanzar una ejecución inicial para activar la conexión de la aplicación con nuestra cuenta de Google Drive:
$ gdrive-linux-x64 about
Authentication needed
Go to the following url in your browser:
https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=367116223233053-7n0vf5akeru7on6o2fjinrareaccpdoe99eg.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3A33qb&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&state=state
¿Qué es esto?, pues una URL que hay que pegar en el navegador web, tras esto nos pedirán las credenciales de nuestra cuenta Gmail y mostrará esta pantalla:


Pinchando sobre "Permitir" nos dará el código de validación:
Copia este código, ve a tu aplicación y pégalo en ella:
4/Pvl90areaertc323a8acedTee9Jgoc
Copiando el código "4/Pvl90areaertc323a8acedTee9Jgoc" o el que nos salga, nos vamos al terminal desde donde hicimos "gdrive-linux-x65 about" y lo pegamos:
Enter verification code: 4/Pvl90areaertc323a8acedTee9Jgoc
Nos contestará con:
User: Tu nombre, tu.cuenta@gmail.com
Used: 6.0 GB
Free: 10.1 GB
Total: 16.1 GB
Max upload size: 5.2 TB
Una vez hecho esto ya tenemos la cuenta autenticada en gdrive (se ha creado un fichero en ~/.gdrive/token_v2.json, ojo con su custodia porque da acceso a nuestro Google Drive) y ya podemos lanzar la descarga usando el id del fichero en cuestión:
# gdrive-linux-x64 download 0B8np4HndYC-lQi0wamstRHF1S3M
Si es un fichero de varios Gigas y va a llevar horas es aconsejable usar screen como conté aquí.
Y nada mas, descarguen mientras sea gratis.

sábado, 17 de diciembre de 2016

Funciones puppet para añadir líneas a ficheros

Dado que gestionamos gran número de equipos mediante puppet, todo lo que sea automatizar y ampliar las funcionalidades del mismo nos viene bien. Ya mostré aquí un par funciones puppet para facilitar la descarga e instalación paquetes .deb en nuestros clientes, muy útiles cuando tratamos con paquetes sueltos fuera de repositorios que no podemos gestionar mediante el recurso puppet package.

En esta sentido son muy interesantes estos defines para gestionar ficheros de texto: permiten, entre otras cosas, añadir o borrar líneas de los mismos. Mi compañero Esteban los ha mejorado mucho, como podemos ver en su blog.

Por mi parte, y basándome en lo anterior he programado varias funciones más. La primera permite añadir una línea por encima de otra identificada por un patrón:
# cat /etc/puppet/defines/add_line_above.pp
#Añade la linea "line" al fichero "file", siempre que la cadena "search" no esté en el fichero.
#La línea la añade inmediatamente por encima de la línea que contenga la cadena "above".
#Usado por ejemplo para añadir lineas a /etc/rc.local por encima del "exit 0" con el cual
#siempre finaliza dicho script.

define add_line_above($file, $line, $search, $above) {
    exec { "/bin/sed -i --follow-symlinks '/${above}/i\\${line}' '${file}' ":
           unless => "/bin/grep -q '${search}' '${file}'"
    }
}
La segunda permite añadir una línea por debajo de otra identificada por un patrón:
# cat /etc/puppet/defines/add_line_below.pp
#Añade la linea "line" al fichero "file", siempre que la cadena "search" no esté en el fichero.
#La línea la añade inmediatamente por debajo de la línea que contenga la cadena "below". 
#En resumen: añade lineas al script por debajo de una linea dada, siempre y cuando no encuentre
# un patrón en el fichero. 
define add_line_below($file, $line, $search, $below) {
    exec { "/bin/sed -i --follow-symlinks '/${below}/a ${line}' '${file}' ":
           unless => "/bin/grep -q '${search}' '${file}'"
    }
}
La tercera permite añadir una línea en una posicion concreta dentro del fichero.
# cat /etc/puppet/defines/add_line_number.pp
#Añade la linea "line" al fichero "file", siempre que la cadena "search" no esté en el fichero.
#La ubica justo despues de la línea "pos" del fichero, quedando en la linea "pos+1" y desplazando
#las posteriores hacia abajo.

define add_line_number($file, $line, $search, $pos) {
    exec { "/bin/sed -i --follow-symlinks '${pos} a ${line}' '${file}' ":
           unless => "/bin/grep -q '${search}' '${file}'"
    }
}
Comentarios:
  • Estos ficheros .pp se guardarán /etc/puppet/defines/... del servidor puppet.
  • Dentro de nuestras clases haremos al comienzo import "/etc/puppet/defines/*.pp" para poder usarlos.
  • El --follow-symlinks del sed sirve para que si el fichero es un enlace simbólico que apunta a un fichero real ubicado en otro lugar, los cambios se hagan sobre el fichero real. Si no se especifica sed crea un nuevo fichero distinto del fichero real, que permanece inalterado.
  • En los tres casos file es el fichero donde buscar, line es la línea a insertar y search es la cadena a buscar para determinar si se inserta o no lo la línea.
  • El cuarto parámetro depende de la funcion.
Ejemplos de uso:
import "/etc/puppet/defines/*.pp"
class .... {

 #============================================================================================================================
 #Anade a rc.local (si no esta ya) el codigo que desactiva en el arranque la tarjeta de audio HDMI de la tarjeta grafica
 #lo hace justo antes de la linea exit 0.

 add_line_above { desactiva_audio_hdmi_siatic:
              file=> "/etc/rc.local",
              line=> 'bus=$(lspci | grep "Audio device: NVIDIA Corporation" | cut -d" " -f1) ; test -n $bus && echo 1 > "/sys/bus/pci/devices/0000:$bus/remove"',
              search=> "NVIDIA Corporation",
              above=> "^exit 0$"
 }

 #============================================================================================================================
 #Anade a etckeeper-commit-post (si no esta ya) una llamada al script /usr/bin/puppet_post_send
 #lo hace justo después la linea que contiene PATH.

 add_line_below { run_post_puppet:
              file=> "/etc/puppet/etckeeper-commit-post",
              line=> '/usr/bin/puppet_post_send',
              search=> "/usr/bin/puppet_post_send",
              below=> "PATH"
 }
}
Nos despedimos con un consejo del Estado: