Lunes 24 de abril de 2017

Asociación LiGNUx: El reproductor MPV Player acaba de llegar a la versión 0.25
Baltasar Ortega

Baltasar Ortega
KDE Blog

Cómo hacer que tu Plasma 5 se parezca a Unity

Tras la controversia de Ubuntu y su abandono del proyecto Unity (un escritorio alternativo para su distribución) la Comunidad KDE vuelve a demostrar que en cuestión de personalización su escritorio no tiene rival. Y es que en apenas 30 segundos nos explican cómo hacer que tu Plasma 5 se parezca a Unity utilizando la potencia de los Look and Feels packs.

Cómo hacer que tu Plasma 5 se parezca a Unity

De la mano de KDEOK nos llega un simple vídeo donde transforman un Plasma 5 con su estilo Breeze claro a un Plasma 5 con un estilo Unity. Evidentemente la transformación no es total, supongo que algunas de las funciones de su barra lateral no estarán del todo integradas pero visualmente son clavados.

Para realizarlo se ha utilizado las opciones de personalización de las Preferencias del Sistema, concretamente la posibilidad de bajarse de la red el Pack de Look and Feel “United” y, a continuación, instalarlo y activarlo. Simple, sencillo y ultrarrápido. ¿Qué mas se puede pedir?

Evidentemente, United tiene un creador que se llama LLucas y que estará encantado en recibir “feedback”: puntúale positivamente, hazle un comentario en la página o realiza una donación. Toda acción, por pequeña que parezca, es importante y valiosa, y en muchas ocasiones apenas cuestan un minuto.

¿Qué son los Look and Feel Packs?

Básicamente se trata de unos packs de personalización que afecta a la gran mayoría de los módulos de estilo de Plasma 5 (decoración de ventanas, colores, barras de tareas, estilos de ventana, etc) que pueden ser activados directamente en el módulo Aspecto Visual de la subsección Tema del espacio de trabajo de la sección Aspecto.

Si os habéis hecho un lío os recomiendo que leáis esta entrada donde se explica con más detalle. Este módulo tiene la opción de conectarse KDE Store y bajar nuevos Look-and-Feel Packs con los que cambiar TODO Plasma de un tirón. Espectacular.

 

 

Gaspar Fernández

Gaspar Fernández
Poesía Binaria

Un monitor VGA que a veces no quiere funcionar enchufado a un puerto HDMI… con script chapuza

Todo me sucedió hace algo menos de un año cuando compré un nuevo portátil de la sexta generación de Intel. Estos portátiles ya no traen puerto VGA. Sencillamente los Skylake de Intel no los soportan y no hay mucho que podamos hacer. Y, si nuestro portátil trae ese puerto, o bien la placa base tiene un adaptador integrado (aunque a estas alturas no sé si habrá algún fabricante que meta un puerto así en un portátil de última generación), o no es un Skylake (de ahí en adelante. Tampoco será un Kaby Lake).

Al mismo tiempo, ya le tenía cariño a mi monitor externo. Un Samsung 4:3 con el que llevaba ya 10 años (ya pronto cumplirá 11) y que sigue funcionando como el primer día a pesar de llevar a sus espaldas varias mudanzas, algún que otro golpe y muchísimas horas de vuelo.

Adaptadores HDMI – VGA

Lo primero fue adquirir Adaptador HDMI a VGA como el que muestro en la foto a continuación. Lo más fácil es buscar a partir del enlace anterior o mirar en un chino. También lo puedes encontrar con salida de audio. Suelen rondar los 7€ sin audio y lo 9-10€ con audio.

Aunque, esto puede ser una solución ideal y muchas veces no es mala solución. Por ejemplo si tienes un Raspberry Pi y lo quieres usar con tu viejo monitor no te queda otra. Y, aunque no lo he probado, dicen por ahí que se portan bien con este tipo de adaptadores. No suelen calentarse mucho, a mí me dio la impresión al principio, hasta que noté que estaba justo delante de la salida de aire del portátil.

El problema

Este tipo de adaptadores suele tener problemas a la hora de comunicar la información del monitor al ordenador. Es decir, toda la información EDID que envía el monitor para identificarse, decir qué resolución soporta, y demás. Y eso provoca que muchas veces enchufemos el monitor y no funcione. Aunque cuando lo tengas un rato enchufado sí que funcione. A veces, la información EDID llega y otras veces no llega. Puede depender del conversor, aunque si lo compras en un chino, la devolución puede llegar a ser odiosa. De todas formas, mirando por Internet, no fui el único que le pasaba esto.

Otro problema es el refresco de la pantalla (cuando funcionaba la pantalla), puede que tras enchufar el conversor, notéis un cierto desfase en la pantalla. Por ejemplo, al reproducir un vídeo, veáis una línea horizontal o varias dividiendo el vídeo. O incluso cuando ponéis una pantalla de terminal o de bloc de notas pase un tiempo perceptible desde que pulsáis la tecla hasta que veis la letra en pantalla. Y no es cosa del ordenador, porque, en el caso del portátil, pude poner la misma ventana en el panel e iba mucho más rápido. Incluso intentar que la misma letra se representara en las dos pantallas a la vez y en la pantalla externa tardaba un poco más.

El problema del refresco

Para solucionar el problema del refresco sólo jugué con los valores de refresco de la pantalla, sincronización vertical y horizontal. Hasta que encontré un punto satisfactorio y que funcionaba siempre. Es cierto que en ocasiones me daba algún bote la pantalla con el driver nvidia, pero cuando pasé del kernel 4.4 a la versión 4.8 todo empezó a ir mucho más fluido.

El problema de la detección

Aunque lo que más me preocupaba es que no me detectaba el monitor a la primera. Para mí no era mucho problema porque apenas apago el ordenador. Lo tengo funcionando todo el día, a todas horas, pero aunque sea una vez al mes lo reinicio. Y es que cuando lo reiniciaba podía estar desde un par de minutos hasta varias horas sin poder utilizar el monitor externo. Por un lado, el problema era del driver de NVIDIA. Al ser un portátil con doble tarjeta gráfica, podía comprobar que con el driver de Intel el monitor lo detectaba mucho antes (a veces no, pero eran las menos). Aunque por otro lado, también era culpa del adaptador, porque cuando enchufo un monitor HDMI en el ordenador todas las ventanas (incluso la configuración de la BIOS) se podían ver por el monitor (cosa que no pasaba cuando tenía el adaptador puesto).

Así que investigando cómo hacerlo podíamos encontrar información útil. Todos los ejemplos los pondré utilizando xrandr porque para mí era mucho más cómodo que hacerlo en xorg.conf

Lo primero será cambiar el proveedor de salida, es decir, quién se encarga de gestionar la salida de vídeo. Podemos obtener una lista de proveedores de:

xrandr --listproviders

Y luego seleccionar el proveedor que deseemos. Este es mi caso, pero tal vez en vuestro sistema sea diferente:

xrandr --setprovideroutputsource 2 0

Tenemos que tener cuidado con esto, ya que si introducimos un valor ilegal en versiones antiguas de Xorg (me pasó con una Ubuntu 16.04), se puede quedar el ordenador congelado. En versiones más nuevas, ya nos avisa del problema y no hace cambios en el sistema.

Por otro lado, debemos insertar el modo de pantalla a mano. Ya que el problema es al comunicar la resolución soportada del monitor al ordenador. El ordenador no la coge bien y no representa nada. Así que digámosle la información del monitor a mano. En mi caso, la resolución era 1280×1024 a 60Hz y, aunque mi ordenador sólo tiene un puerto HDMI, el nombre con el que el sistema lo detecta es HDMI-1-2 (el nuevo driver de NVIDIA tiene nombres muy largos). Además, quiero la pantalla a la derecha de la del panel del portátil. Para eso hacemos lo siguiente:

xrandr --newmode “1280x1024_60.00” 108.88  1280 1360 1496 1712  1024 1025 1028 1060  -HSync +Vsync
xrandr --addmode HDMI-1-2 1280x1024_60.00
xrandr --output HDMI-1-2 --mode 1280x1024_60.00 --right-of eDP-1-1

Y ya tenemos que tener el monitor funcionando.

Kde Plasma 5

Con la llegada de KDESC 5, llega el nuevo escritorio Plasma y un montón de innovaciones y cosas chulas que podemos hacer. Pero la gestión de la pantalla, cuando creamos un modo de vídeo a mano nos empieza a dar problemas. El modo de vídeo se crea, y podemos representar cosas en la pantalla, pero no tenemos fondo de escritorio y algunos efectos se verán un poco raros, porque para KDE es como si no tuviéramos pantalla. Es más, si accedemos a la configuración nos dice disconnected, aunque la pantalla está claramente enchufada y hay imágenes en pantalla. Esto con un monitor HDMI directamente no pasa..
El problema aquí es que KDE le pregunta a su proveedor, xrandr si hay monitor, y como el monitor no manda bien la información (algunos programas existentes para leer la información EDID devuelven error en el checksum), el proveedor devuelve un error y el monitor figurará como desconectado. Dado que algunas veces sí que se envía bien la información y por lo tanto, el monitor aparecerá como conectado, dando el aspecto que tiene que tener la imagen, vamos a intentar pedir la información al monitor hasta que nos la devuelva bien. Con cuidado, porque, aunque nos la devuelva bien, si volvemos a preguntar, tal vez la entregue mal de nuevo y nos toque volver a empezar.

Para ello, tenemos este script:

while [ -n “$(xrandr | grep ‘HDMI-1-2.*disconnected’)” ]; do sleep 1; done

Con esto, estaremos llamando a xrandr, que refrescará la información del monitor, y mirará si junto con el nombre de la salida, HDMI-1-2, figura también el mensaje disconnected. Si es así, espera un segundo y vuelve a intentar. Así, puede que en unos minutos tengamos el monitor detectado. Otra solución es dejarlo enchufado, a veces lo solía coger solo, aunque podía tardar horas.

El caso en Windows

Pero claro, muchos pensaréis que es cosa de GNU/Linux. El caso es que Windows (probé Windows 10) sí que terminaba detectando el monitor y más o menos pronto. Como mucho entre uno y cuatro minutos. El problema, es que tras enchufar el monitor externo con el conversor, el sistema quedaba congelado, y las pantallas parpadeando durante todo ese tiempo, aunque al final el monitor funcionaba sin tener que hacer scripts ni nada raro.

Foto: Caspar Rubin

The post Un monitor VGA que a veces no quiere funcionar enchufado a un puerto HDMI… con script chapuza appeared first on Poesía Binaria.

Miguel Parada

Miguel Parada
Ubuntizando.com

Ya disponible Linux Lite 3.4. La distribución pensada para revivir tu viejo PC

Si buscas una distribución ligera o bien tu equipo no tiene demasiada potencia como para poder correr las distribuciones más populares quizá debas darle una oportunidad a Linux Lite. Recientemente acaba de publicarse la versión 3.4, basada en Ubuntu y capaz de revivir tu viejo PC ya que con 500MB de RAM es más que suficiente para ejecutarlo en máquinas de 32 bits. Yo mismo la he probado en un equipo con poco más de 300MB de RAM y apenas he notado ralentizaciones en tareas básicas.

Su escritorio está basado en una versión de XFCE y prescinde de todo aquello que puede recargar nuestro sistema. Además cuenta con varias herramientas de limpieza y optimización integradas de modo que podemos desactivar o activar servicios a golpe de click ajustando la distribución a nuestras preferencias. Sin duda una distribución fantástica.

Nota: Por cierto. Ubuntizando ha sido nominado a los premios Open Awards 2017 como mejor Blog.  ¿Nos ayudas con tu voto? 😉

Votanos como mejor blog en los Open Awards 2017

Domingo 23 de abril de 2017

Miguel Parada

Miguel Parada
Ubuntizando.com

CHUWI necesita tu opinión y de paso puedes llevarte una Surbook gratis

No es la primera vez que hablo de CHUWI en este blog. Desde que tengo en mi poder una de sus tablets (CHUWI Hi1o Pro) estoy muy atento a las novedades de este fabricante.  En estos momentos se encuentra en una interesante promoción tras finalizar su última campaña de crowdfunding en indieGOGO para lograr la financiación necesaria para fabricar su próximo modelo. La CHUWI Surbook promete ser una “SurFace Killer” en muchos aspectos ya que cuenta con un procesador Intel Apollo Lake Lake N3450 (pequeño pero potente) y un chipset gráfico Intel HD Graphics de novena generación a un precio asequible.

Dentro de este dispositivo de 12,3 pulgadas (2736 x 1824 píxeles de resolución), encontramos además 6GB DDR de RAM y un almacenamiento de 128GB eMMC. Totos esto alimentado por una batería de 10.000 mAh de capacidad que garantiza más de 6 horas de autonomía.

Pero en lo personal lo realmente importante de esta campaña es que CHUWI quiere conocer nuestra opinión y mejorar así sus futuros productos en una iniciativa donde dejando tu comentario y siguiendo las condiciones del sorteo puedes hacerte con una Surbook, de las dos que sortean, en cuanto salga a la venta. En mi caso, como no podría ser de otro modo, les he pedido que mejoren el soporte a GNU/Linux ya que hay muchos usuarios que no gustan de Windows 10. Supongo que si muchos otros usuarios hacemos una crítica similar acabarán por hacernos caso. El plazo finaliza el próximo 29 de abril así que toca darse prisa. 🙂

Tenéis más información de la promoción en el siguiente enlace.

 

 

Baltasar Ortega

Baltasar Ortega
KDE Blog

Programa de actividades de Linux&Tapas 2017 de León

Ya he hablado de este evento antes, pero es que me parece tan fabuloso y ahora tengo mucha más información que me apetece promocionarlo un poco más. Y es que se ya publicado ya el programa de actividades de Linux&Tapas 2017 de León, así como puesto a la venta algún que otro merchandising del encuentro.

Programa de actividades de Linux&Tapas 2017 de León

Programa de actividades de Linux&Tapas 2017 de LeónComo es tradición desde hace unos años, se va a celebrar el próximo 6 de mayo  Linux&Tapas 2017 de León en el casco antiguo de León, concretamente en el conocido Barrio Húmedo, donde unos locales ya han confirmado que serán utilizados para la parte gastronómica del evento y otros individuos han decidido pasar la tarde contando sus batalitas en forma de charlas.

Lo podéis ver todo en el programa de actividades que ya ha sido publicado:

12:30 – 13:00: Quedada en la Plaza de la Catedral de León

13:00 -16:30: Feria de la tapa lyt17

17:00 – 20:00: Ponencias en la Fundación Sierra Pambley:

  • “Radio Universitaria, ¡en el aire Libre!” Eloy
  • “El cuento de la gallina de los datos de oro”. Pablo Marinero
  • “Is it a game or is it real?” Fran
  • ” Autodefensa Digital”. Jorge SoydelBierzo

21:00 – ∞: Fiesta de despedida

Además, si quieres llevarte un recuerdo inolvidable del evento te informo que también se han elaborado camisetas del mismo, realizadas por gráficas Quearte que se han encargado también de la cartelería y las chapas. Se pueden reservar una de ellas por el módico precio de 15€ reservándolas previamente. Si te interesa no dejes de visitar la entrada del blog donde se cuentan los detalles.

 

 

Si estuviera por la zona ni me lo pensaba, así que si tú lo estás no dudes en inscribirte. Y si te pilla lejos pero te apetece ir, tampoco te lo pienses e inscribirte también. Simplemente viendo la página de anteriores eventos ya da ganas de ir.

 

 

Más información: Linux&Tapas 2017

Asociación LiGNUx: Prepárense, Devuan is coming!

Sábado 22 de abril de 2017

Liher Sanchez

Liher Sanchez
El blog de Liher

Otra de juegos

Hace poco os hablé de los juegos que me gustan ahora mismo y de los que he usado desde que empecé en esto de la informática. Hasta que no conseguí mi primer trabajo no tuve consola de videojuegos por lo que los juegos que usaba antes de eso eran siempre en el ordenador. Aquel artículo tuvo una buena acogida y algunos usuarios me hablaron de mas juegos, así fue como recordé otros juegos que había usado y que se me habían quedado en el tintero. Es por ello que he decidido escribir otro post recordándolos.

En aquel articulo os hablaba, entre otros, de un juego llamado The secret of Monkey island, un juego del que guardaba muy buenos recuerdos, hasta el punto que su famosa melodía de entrada se ha convertido en mi alerta de notificaciones en el móvil. Os hablo de la melodía en formato MIDI, me encanta. Por si algunos no la conocéis os dejo aquí un enlace a un vídeo de Youtube en el cual se puede escuchar como sonaba dicha melodía en diferentes tarjetas de sonido. para que la oigáis. En mi ordenador sonaba como la primera canción, desde el primer segundo hasta el minuto 1 y 28 segundos. Los que hayáis usado ese juego seguro que recordáis esa melodía con nostalgia.

Uno de los juegos que mas horas me llevó y que no mencioné en mi anterior artículo fue el PCFutbol, desde la versión que venia en un diskete hasta la que venia en CD. La de horas que pude meterle haciendo fichajes, creando alineaciones, formaciones y demás parafernalias que se podían hacer en el juego. Ya en las máquinas recreativas un juego que me llevó muchas horas también fue el Street fighter 2 y el Bubble Bobble, os dejo un par de imágenes.

 

street fighter 2

 

 

También recuerdo juegos como el Ghosts ‘n Goblins y el Altered Beast. Con este último recuerdo una anécdota cortita que os voy a contar. Tenia yo unos 12 años cuando, en frente de donde viven mis padres, había una sala de juegos. En ella, entre otras, estaba una máquina recreativa que tenía el Altered beast y era un juego que me llama mucho la atención. Pues bien, un día estaba mirando como jugaba otro chico, mayor que yo, quizás tenia 17 años, y yo tenia la cabeza tan metida mirando el juego que le impedía la vista y me dió una colleja de tal forma que me mi un pequeño cabezazo contra la pantalla de la máquina, de esa forma aprendí que unos centímetros mas atrás podía ver igual el juego sin molestar 😀

 

 

Una cosa que siempre me ha gustado es jugar a un juego y empezar desde cero para ir creciendo, os pongo un ejemplo con el PCFutbol, elegía un equipo pequeño y le llevaba a ganar la Champions League. Eso me pasa hoy en día también, con el Clash of clans, por poner un ejemplo y me ha pasado también con otros juegos como el juego de video poker online, al cual también estuve jugando una temporada y me gustaba el tema de ir amasando fortuna e ir subiendo de nivel para ganar mas reputación y entrar en partidas de mas alto nivel. También me gustaba mucho jugar al billar, siempre me ha gustado y hecho de menos las partidas al billar de carambolas, ahora cada vez cuesta mas encontrar un billar. Y como no podía ser de otra manera el futbolín me ha llevado muchas tardes con mis amigos, otra cosa que echo de menos.

Bueno, espero haber revivido algunos buenos ratos que hayáis pasado con los videojuegos o el billar rodeados de vuestros amigos y arrancaros una pequeña sonrisa de nostalgia. Un saludo a todos.

David González

David González
Blog Bitix

Información sensible en los contenedores con Docker Secrets

Parte de la información que usan los contenedores de Docker se debe proteger de accesos no deseados. Anteriormente en algunos casos se usaban variables de entorno para lanzar los contenedores lo que no es seguro si se listan los procesos del sistema con sus parámetros, incluir archivos en las imágenes de los contenedores tampoco es recomendable. Docker Secrets permite proporcionar y mantener segura la información sensible que usen los contenedores.

Docker

Los contenedores de Docker necesitan acceder a algunos datos sensibles desde el punto de vista de la seguridad como usuarios y contraseñas, certificados SSL, claves privadas SSH o cualquier otra información de acceso restringido. Algunos de estos datos en Docker se proporcionan mediante variables de entorno al lanzar los contenedores, esto es inseguro ya que al hacer un listado de los procesos con sus parámetros de invocación los relativos a Docker mostrarán esta información, lo que es un posible problema de seguridad.

Con Docker Secrets se puede gestionar esta información que se necesita en tiempo de ejecución pero que no se quiere almacenar en la imagen de Docker o en el repositorio de código fuente. Algunos ejemplos de información sensible son:

  • Nombres de usuario y contraseñas.
  • Certificados TLS y claves.
  • Claves SSH.
  • Otra información sensible como el nombre de una base de datos o el nombre de un servidor interno.

Los secretos de Docker se proporcionan a los contenedores que los necesitan y se transmiten de forma cifrada al nodo en el que se ejecuten. Los secretos se montan en el sistema de archivos en la ruta /run/secrets/<secret_name> de forma descifrada al que el servicio del contenedor puede acceder.

Algunos comandos para manejar los secretos son los siguientes:

  • docker secret create secreto: crea un secreto.
  • docker secret inspect secreto: muestra los detalles de un secreto.
  • docker secret ls: lista los secretos creados.
  • docker secret rm secreto: elimina un secreto.
  • Se usa el parámetro –secret para docker service create y –secret-add y –secret-rm flags para docker service update.

Usando un stack de servicios con un archivo de Docker Compose en la sección secrets de los servicios se indica cuales usa, en la sección secrets se definen los secretos de los servicios con sus nombres y su contenido referenciando archivos que pueden ser binarios o de text no superior a 500 KiB.

Al servicio de nginx la clave privada y certificado para configurar el acceso mediante el protocolo seguro HTTPS se le proporciona a través de secretos que son referenciados en el archivo de configuración del servidor web nginx.conf.

Por otra parte la aplicación Java con Spring Boot lista el contenido de los secretos incorporados en el contenedor cuando se solicita en la URL https://192.168.99.100/system/info/, esto no se debe hacer porque se pierde la seguridad que proporcionan los secretos pero sirve a modo de muestra en el ejemplo.

Contenido del archivo message.txt

Para probar el ejemplo hay que ejecutar varios comandos, la secuencia completa es la siguiente:

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub.

Baltasar Ortega

Baltasar Ortega
KDE Blog

Nftables en las charlas de Barcelona Free Software

Eventos, eventos, eventos, el mundo del Software Libre está lleno de eventos donde compartir conocimientos y experiencias. Hoy me toca hablar de los eventos patrocinados por la Comunidad de KDE de Barcelona.  Hace unos días se presentó una nueva ponencia dedicada a Nftables en las charlas de Barcelona Free Software. Una forma de conocer un proyecto que nace con la idea de mejorar nuestros sistemas GNU/Linux.

Nftables en las charlas de Barcelona Free Software

Siguen las charlas de la temporada 2016-17 del grupo Barcelona Free Software. En esta ocasión se ha vuelto a cambiar la sede, así que atentos y no os despistéis.

En este caso se trata de Nftables, un proyecto que según leeemos en la Wikipedia,  proporciona filtrado de paquetes y clasificación de paquetes en Linux, destinado a reemplazar los frameworks existentes iptables, ip6tables, arptables y ebtables.

Esta charla será presentada por Pablo Neira Ayuso, desarrollador recomendado por la FSFE, el cuál ha estado desarrollando nftables desde hace un tiempo, aportando su contribución al Kernel.

Nftables en las charlas de Barcelona Free Software
Recuerda los datos importantes:

Además, recuerda que tendremos el usual “networking” con cerveza gratis incluida. Este meetup está organizado por KDE España, la asociación nacional de usuarios y desarrolladores de KDE, un proyecto de software libre que crea el Plasma Desktop y cientos de aplicaciones usando Qt y QML

No te lo pienses. ¡Te esperamos el viernes 28 de abril!

Más información: Barcelona Free Software

¿Qué es Meetup?

Las charlas de Barcelona Free Software se organizan mediante Meetup, una red social que tiene una diferencia básica respecto a otras redes sociales, ya que  promueve la formación de grupos en torno a intereses con el fin de que sus miembros se conozcan cara a cara.

Es decir, los usuarios establecen contacto a través de grupos digitales nuevos o ya creados, partiendo de intereses comunes como política, libros, juegos, películas, salud, mascotas, profesiones y muchos más, para después hacer un “meetup”, es decir, un encuentro presencial en algún lugar convenido, donde nunca faltan las cervezas.

Asociación LiGNUx: ¡Camarero!¡Póngame una de Ubuntu!

Viernes 21 de abril de 2017

Wires For Empathy: una nueva película «de código abierto»

Hoy me he encontrado con un nuevo proyecto cinematográfico construido completamente con software libre y que, una vez terminado, será distribuido con licencias CC y GNU-GPL: Wires For Empathy https://wiresforempathy.org/images/samples.mp4 Inspirada en la epopeya de Gilgamesh, esta película reúne los esfuerzos de 76 artistas trabajando desde 22 países.  En el vídeo no se adelanta mucho […]
Miguel Parada

Miguel Parada
Ubuntizando.com

Audrey Tang, la ministra ‘hacker’ de Taiwán, confirma su participación en la OpenExpo

 

El próximo 1 de junio se celebra la OpenExpo, un importante evento donde la comunidad española de Open Source y Software Libre tiene una cita para hablar sobre la actualidad del sector. Este año cuenta además con la participación de importantes figuras como es el caso de Audrey Tang, la primera ministra digital del mundo que ha revolucionado el sector por ser la primera mujer en ocupar el cargo y la más joven del gobierno. Audrey, con un coeficiente intelectual de 180 y una carrera precoz, defiende que la red debería ser más colaborativa y aboga por la transparencia del gobierno.
La taiwanesa va a ofrecer en exclusiva a través de OpenExpo, un webinar en el que impartirá una presentación técnica sobre cómo se usa Sandstorm.io en el Gobierno de Taiwán. Sandstorm es una solución web de código abierto para la productividad, basada en contenedores Linux. En este webinar, se compartirá la historia del papel de PDIS.tw (Public Digital Innovation Space) en su desarrollo y despliegue.
El webinar, avalado por OpenExpo, se llevará a cabo el próximo viernes 28 de abril de 10:30h a 12:00h (hora española). Toda la información sobre la sesión online está contenida en el siguiente enlace donde puedes regístrate para que la organización te pase los datos de la conexión el día antes.

 

 

 

 

Nota: Por cierto. Ubuntizando ha sido nominado a los premios Open Awards 2017 como mejor Blog.  ¿Nos ayudas con tu voto? 😉

Votanos como mejor blog en los Open Awards 2017

Jueves 20 de abril de 2017

Conocer las características OpenType ofrecidas por una fuente

Hace unos meses un lector me preguntaba si conocía un visor de fuentes en Linux que mostrara las características ofrecidas por una fuente. En ese momento no conocía ninguno, pero resulta que descubrir las opciones OpenType disponibles es bastante simple desde la línea de comandos. Todo lo que necesitamos es la instrucción «otfinfo» que viene […]

Vuelve a usar tu 64bits con FatDog

Con el tiempo, vamos acumulando hardware no tan moderno o potente como los de ahora. Seguramente sepas de lo que estamos hablando si ya llevas unos años en eso de la informática y has tenido que sustituirlo por otro, por culpa de que al actualizar a la nueva versión de tu distribución favorita, ya no funciona en óptimas condiciones. Hoy te traemos una de las distribuciones más
Gaspar Fernández

Gaspar Fernández
Poesía Binaria

¿Cómo visualizar la progresión del código fuente de un proyecto en vídeo?

Nos gusta desarrollar, y muchas veces, sobre todo cuando el equipo de desarrollo es grande, apetece enseñar la evolución de nuestro código a los demás de una forma visual. Y, ¿qué mejor que con un vídeo? Un vídeo nos ayudará, de un vistazo a ver lo grande que es nuestro proyecto, las épocas de más o menos cambios, los usuarios implicados, etc. Y luego puedes colgar el vídeo en alguna red social de vídeos, utilizarlo como apoyo para presentaciones, y mucho más. Por cierto, no sólo está limitado a nuestros proyectos, cualquier código al que podamos acceder por git, svn, csv, etc será susceptible de ser convertido en vídeo.

Visualizar código con gource

Gource es un programa que hace una representación de los repositorios en el tiempo. Analiza el contenido de los logs y crea una muestra en pantalla con movimientos suaves y efectos de luces utilizando OpenGL. El software se puede ejecutar tanto en Linux como Windows y es muy estable, lo he probado en repositorios de varios gigas y casi 10 años de commits sin problema. Es verdad que si hacemos un vídeo, sobre todo por la resolución y la conversión de vídeo va un poco más lento, pero es algo que puede quedarse en segundo plano.

Para los ejemplos, he utilizado el repositorio de GitHub del proyecto openshot-qt. Porque me ha parecido interesante hacerlo con este proyecto.

Combinación con ffmpeg/avconv

Gource, es incapaz de exportar a vídeo, pero como en la mayoría de aplicaciones que ejecutamos en GNU/Linux, podemos encadenar comandos y pasar el flujo de datos de una aplicación a otra, por ejemplo, una aplicación como ffmpeg o avconv con la que podemos hacer pasar streams de imágenes y guardarlas en formato vídeo con el formato que queramos… o incluso le podemos añadir música o efectos si pasamos el vídeo a los programas adecuados.

En principio, vamos a guardar nuestro vídeo generado con gource en un archivo de vídeo, y para ello utilizaremos la salida en formato de secuencia de imágenes PPM que nos da gource y lo encadenaremos con una tubería hasta avconv, con el que crearemos el vídeo definitivo:

gource -1920×1080 openshot-qt/ --stop-at-end -s 1 -c 1.6 --camera-mode track --multi-sampling -r 25 --user-scale 3 --highlight-users --disable-progress -a 1 -o --  | avconv -y -r 25 -f image2pipe -c:v ppm -i pipe:0 -threads 1 -c:v libx264 -preset ultrafast -f mp4 videofinal.mp4

Expliquemos esto un poco:
  • -1920×1080 : Indica la resolución. Vamos a hacer un vídeo en Full HD.
  • openshot-qt/ : Es el directorio del repositorio, debemos indicar un directorio que tenga algún tipo de control de versiones: git, svn, csv…
  • –stop-at-end : El programa finalizará cuando termine de analizar commits. En realidad este argumento no es necesario, porque -o implica que se pare al finalizar, pero nos viene bien por si queremos practicar un poco con gource antes de crear el vídeo.
  • -s 1 : Nos dará la velocidad de la simulación en segundos por día. Aunque en realidad el número de segundos que tiene un día en el repositorio puede variar dependiendo del número de commits que haya ese día.
  • -c 1.6 : Acelera la simulación un poco. 1 sería mantenerla a la misma velocidad. 4 sería el máximo.
  • –camera-mode track : los modos válidos son overview y track. Probad los dos y quedaos con el que más os guste.
  • –multi-sampling : reduce el aliasing de un modo económico.
  • -r 25 : mi vídeo tendrá 25 fotogramas por segundo.
  • –highlight-all-users : resalta los nombres de todos los usuarios. Podemos, si queremos resaltar un usuario concreto con –highlight-user [nombre_de_usuario]
  • –disable-progress : Elimina la barra de progreso en la ventana de gource. No haría falta, puesto que -o anula esta configuración. Pero, como antes, si queremos investigar nos viene bien.
  • -a 1 : Si no hay commits durante un segundo, saltamos al siguiente commit en el tiempo.
  • -o – : Exportamos el vídeo generador en formato de secuencia de imágenes PPM. Aquí podemos dar un nombre de archivo base o, como en este caso – indicará que las imágenes se exportarán en la salida del programa. Si lo ejecutamos tal cual, se empezará a llenar la terminal de símbolos raros. Es mejor poner – sólo cuando vayamos a encadenar con otro comando.

Ahora bien, hemos terminado de analizar los argumentos para gource, ahora la salida de este programa la vamos a pasar a la entrada de avconv (esto lo hacemos con |, que indicará una tubería o pipe). Analicemos los argumentos de avconv:

  • -y : No pide confirmación para sobreescribir los archivos. Es útil cuando estamos haciendo pruebas, pero por seguridad podríamos quitarlo.
  • -r 25 : El número de fotogramas por segundo, 25. Lo especificamos en gource, pero lo volvemos a indicar aquí para que los dos programas trabajen a la misma velocidad. Podríamos jugar con estos parámetros para conseguir más o menos velocidad.
  • -f image2pipe : El formato de los datos de entrada será en forma de secuencia de imaǵenes a través de pipe (la tubería que hemos hecho encadenando los dos programas).
  • -c:v ppm El formato de los datos de la secuencia de imágenes es PPM. (Para que gource y avconv hablen el mismo idioma).
  • -i pipe:0 : Las imágenes de entrada vendrán por la entrada estándar (0) a través de pipe.
  • -threads 1 : Utilizaremos sólo 1 thread para la compresión. Podremos utilizar más, o no especificar este parámetro para que sea automático y tal vez vaya todo un poco más rápido. Pero si el repositorio es muy grande, y vamos a necesitar varias horas para crear el vídeo, tal vez nos interese poder utilizar el ordenador para otras cosas mientras, así que limito el número de cores a utilizar.
  • -c:v libx264 : Voy a utilizar un format de vídeo h264 (mp4). Puedo especificar si quiero con -b:v los bits por segundo para mi vídeo, para aumentar o disminuir la calidad.
  • -preset ultrafast : libx264 utiliza preconfiguraciones con parámetros para facilitarnos la creación de vídeo, en este caso van determinados por velocidad. Cuanto más lenta se haga la compresión, más pequeño será el archivo, ultrafast, en este caso nos proporciona la compresión más rápida, pero el tamaño de archivo más grande (h264 comprime mucho, pero si ponemos un veryslow aquí veremos una calidad similar y un archivo mucho más pequeño).
  • -f mp4 : Crearemos un archivo mp4. Aquí podremos poner avi, o matroska si lo preferimos. En realidad no hace falta puesto que la extensión del archivo (siguiente parámetro lo especifica, pero está bien para investigar.
  • videofinal.mp4 : nombre de archivo donde vamos a guardarlo.

Ahora, sólo tenemos que dejar que el programa haga lo que tiene que hacer, si el repositorio es muy grande tardará un rato bastante largo. Es importante no cerrar la ventana de gource mientras se está creando el vídeo. Además, podemos manejarla de forma interactiva, haciendo zoom, moviendo o utilizando teclas especiales para mostrar más o menos información.

Añadiendo una pista de música

Un vídeo así queda muy soso, así que vamos a utilizar avconv para añadir una pista de música. Yo he utilizado una pista de Josh Woodward. Un artista que tiene una gran colección de canciones Creative Commons tanto instrumentales como con voz. Así que, le vamos a decir a avconv que utilice una pista de audio de la siguiente forma:

gource -1920×1080 openshot-qt/ --stop-at-end -s 1 -c 1.6 --camera-mode track --multi-sampling -r 25 --user-scale 3 --highlight-all-users --disable-progress -a 1 -o --  | avconv -y -r 25 -f image2pipe -c:v ppm -i pipe:0 -i ~/Descargas/JoshWoodward-NQC-NoVox-03-SheDreamsInBlue.mp3 -threads 1 -c:v libx264 -preset ultrafast -f mp4 videofinal.mp4

Como vemos, es muy parecido a lo de antes, sólo añadiendo una pista más con -i

Vídeo generado

Añadiendo efectos

Pero claro, esto está muy bien, pero en GNU/Linux no estamos limitados a esto. Podríamos crear, directamente, el vídeo añadiendo algún efecto. Avconv dispone de sus filtros, aunque vamos a utilizar filtros de MLT, muchos de estos filtros también se procesan en GPU y utilizan multi-threading, por lo que, aunque a avconv le digamos que utilice solo un thread, tal vez MLT esté haciendo un uso más intensivo de CPU para aplicar sus filtros.
Aunque en futuros posts me dedicaré más a fondo a este software, aquí haremos una pequeña introducción.

Para empezar, la música, en lugar de introducirla con avconv, la voy a introducir con MLT (en adelante, en línea de comandos, será melt). El hecho de hacerlo con melt, es porque melt va a utilizar datos provenientes de una pipe de avconv (es un jaleo, gource pasa datos por pipe a avconv y avconv otra pipe para melt). Mi objetivo era simplificar la pipe para melt y no complicarme la vida exportando el audio también.

Aquí va el pequeño comando:


$ melt -audio-track ~/Descargas/JoshWoodward-NQC-NoVox-03-SheDreamsInBlue.mp3 -track pipe:1 que sería una pipe de salida estándar. Por otro lado, le hemos dicho que el bitrate de vídeo sea de 12000k por segundo.

Luego a melt le hemos dicho:

  • -audio-track [pista.mp3] : Especificamos una pista de audio. ¡La música de fondo!
  • -track
  • -filter sepia : Especificamos un filtro sepia. Podemos probar con muchísimos fitlros. Ejecutad $ melt -query filters para verlos todos
  • -consumer avformat:videofinal.mp4 : Grabamos el vídeo en el archivo videofinal.mp4

Con melt también podemos añadir efectos de audio, fundidos, marca de agua e infinidad de cosas más como veremos en futuros posts.

Sugerencias y comentarios

Deja un comentario debajo con tus dudas, sugerencias, ideas y frikadas. Y si tienes un repositorio del que hayas hecho un vídeo, déjamelo por aquí, seguro que es muy interesante verlo.

The post ¿Cómo visualizar la progresión del código fuente de un proyecto en vídeo? appeared first on Poesía Binaria.

Miércoles 19 de abril de 2017

Novedades de C++17

Después de tres años de trabajo, C++17 ha sido finalmente estandarizado. Esta nueva versión de C++ incorpora y elimina elementos del lenguaje, con el fin de ponerlo al día y convertirlo en un lenguaje moderno y eficaz. El comité ISO de C++ se ha tomado muy en serio su labor, C++11 supuso este cambio de mentalidad, que se ha mantenido en C++14 y ahora en C++17, la última versión de C++.

Repasemos las noveades que incorpora C++17 respecto a C++14

if-init

Ahora podemos incluir una sentencia de inicialización antes de la condición en sentencias if y switch. Esto es particularmente útil si queremos operar con un objeto y desconocemos su validez.

// ANTES
Device dev = get_device();
if(dev.isOk()){
    dev.hacerCosas();
}

// AHORA
if(Device dev = get_device(); dev.isOk()){
    dev.hacerCosas();
}

Declaraciones de descomposición

Azúcar sintántico que permite mejorar la legibiliad en ciertas situaciones. Por ejemplo, en el caso de las tuplas, su uso se vuelve trivial.

// FUNCIÓN QUE DEVUELVE TUPLA
std::tuple<int, std::string> funcion();

// C++14
auto tup = funcion();
int i = std::get<0>(tup);
std::string s = std::get<1>(tup);

// C++17
auto [i,s] = funcion();

Esto funciona para multitud de estructuras de datos, como estructuras, arrays, std::array, std::map,…

std::map m = ...;
for(auto && [key, value] : m){

}

Deduction Guides

Ahora es menos necesario que nunca indicar los tipos en ciertas expresiones. Por ejemplo, al crear pares y tuplas:

// ANTES
auto p = std::pair<int,std::string>(42,"Adrianistan");

// AHORA
auto p = std::pair(42,"Adrianistan");

Esto por supuesto también sirve para estructuras y otras construcciones:

template<typename T>
struct Thingy
{
  T t;
};

// Observa
Thingy(const char *) -> Thingy<std::string>;

Thingy thing{"A String"}; // thing.t es de tipo std::string

template auto

// ANTES
template <typename T, T v>
struct integral_constant
{
   static constexpr T value = v;
};
integral_constant<int, 2048>::value
integral_constant<char, 'a'>::value

// AHORA
template <auto v>
struct integral_constant
{
   static constexpr auto value = v;
};
integral_constant<2048>::value
integral_constant<'a'>::value

Fold expressions

Imagina que quieres hacer una función suma, que admita un número ilimitado de parámetros. En C++17 no se necesita apenas código.

template <typename... Args>
auto sum(Args&&... args) {
   return (args + ... + 0);
}

Namespaces anidados

Bastante autoexplicativo

// ANTES

namespace A{
    namespace B {
        bool check();
    }
}

// AHORA

namespace A::B {
    bool check();
}

Algunos [[atributos]] nuevos

[[maybe_unused]]

Se usa para suprimir la advertencia del compilador de que no estamos usando una determinada variable.

int x = 5;
[[maybe_unused]] bool azar = true;
x = x + 10

[[fallthrough]]

Permite usar los switch en cascada sin advertencias del compilador.

switch (device.status())
{
case sleep:
   device.wake();
   [[fallthrough]];
case ready:
   device.run();
   break;
case bad:
   handle_error();
   break;
}

Variables inline

Ahora es posible definir variables en múltiples sitios con el mismo nombre y que compartan una misma instancia. Es recomendable definirlas en un fichero de cabecera para luego reutilizarlas en ficheros fuente.

// ANTES
// en una cabecera para que la usasen los demás
extern int x;

// solo en un fichero fuente, para inicializarla
int x = 42;
// AHORA

// en la cabecera
inline int x = 42;

if constexpr

Ahora es posible introducir condicionales en tiempo de compilación (similar a las macros #IFDEF pero mejor hecho). Estas expresiones con constexpr, lo que quiere decir que son código C++ que se evalúa en tiempo de compilación, no de ejecución.

template<class T>
void f (T x)
{
    if  constexpr(std:: is_integral <T>::value)  {
        implA(x);
    }
    else  if  constexpr(std:: floating_point <T>::value)  {
        implB(x);
    }
    else
    {
        implC(x);
    }
}

std::optional

Tomado de la programación funcional, se incorpora el tipo optional, que representa un valor que puede existir o no. Este tipo ya existe en Rust bajo el nombre de Option y en Haskell como Maybe.

std::optional opt = f();
if(opt)
    g(*opt);

// otra opción de uso si queremos proveer de un reemplazo
std::optional opt = f();
std::cout << opt.value_or(0) << std::endl;

std::variant

Descritas como las unions pero bien hechas. Pueden contener variables de los tipos que nosotros indiquemos.

std::variant<int, double, std::vector> precio; // precio puede ser un int, un double o un std::vector

// comprobar si el valor en un variant es de un determinado tipo
if(std::holds_alternative<double>(precio))
    double x = std::get<double>(precio);

std::any

Si con std::variant restringimos los posibles tipos de la variable a los indicados, con std::any admitimos cualquier cosa.

std::any v = ...;
if (v.type() == typeid(int)) {
   int i = any_cast<int>(v);
}

std::filesystem

Se añade a la librería estándar este namespace con el tipo path y métodos para iterar y operar con directorios. Dile adiós a las funciones POSIX o Win32 equivalentes.

#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;

void main(){
  fs::path dir = "/";
  dir /= "sandbox";
  fs::path p = dir / "foobar.txt";
  std::cout << p.filename() << "\n";
  fs::copy(dir, "/copy", fs::copy_options::recursive);
}

Algoritmos en paralelo

Muchos de los algoritmos de STL ahora pueden ejecutarse en paralelo bajo demanda. Con std::execution::par indicamos que queremos que el algoritmo se ejecute en paralelo.

std::sort(std::execution::par, first, last);

¿Qué novedades se esperan en C++20?

Ya hemos visto lo que trae C++17. Ahora veremos que se espera que traiga C++20 en 2020.

  • Módulos. Reemplazar el sistema de includes
  • Corrutinas. Mejorar la programación asíncrona
  • Contratos. Mejorar la calidad del código
  • Conceptos. Mejorar la programación genérica
  • Redes. Estandarizar la parte de red en C++ tal y como se ha hecho con std::filesystem
  • Rangos. Nuevos contenedores

Referencias:

 

La entrada Novedades de C++17 aparece primero en Blog - Adrianistan.eu.

Lunes 17 de abril de 2017

Pedro L. Lucas

Pedro L. Lucas
Cartas de Linux

Temas y plantillas en Hugo – Parte 4

En esta serie de artículos sobre el gestor de contenidos Hugo, vamos a centrarnos en los temas.

En el siguiente enlace podemos ver cientos de ejemplos de temas para Hugo:

http://themes.gohugo.io/

Para instalarlos sólo hay que descargarlos y copiarlos en la carpeta themes de nuestro sitio. Aunque la mayoría de los temas los podemos instalar usando el comando git.

Algunos temas nos van a requerir alguna distribución especial de los contenidos o introducir alguna configuración especial en el sitio. Esto lo podemos ver en las descripciones de los temas.

Los temas se crean a través de las plantillas (Templates) de Hugo. Básicamente una plantilla es un fichero html y en el que vamos a encontrar algunas etiquetas especiales del tipo “{{ algo }}”.

Por ejemplo:

<!DOCTYPE html>
<html>
<head>
  <title>{{ .Title }}</title>
</head>
<body>
  <h1>{{ .Title }}</h1>
  {{ .Content }}
</body>
</html>

Esto es una plantilla html del lenguaje Go. Para ver una introducción a este lenguaje podemos consultar la documentación de Hugo sobre las plantillas:

https://gohugo.io/templates/go-templates/

En el ejemplo anterior, se puede ver que aparece la etiqueta “{{ .Title }}”, que lógicamente se reemplaza por el título cuando el sitio se construye. También tenemos la etiqueta “{{ .Content }}”, que se reemplazará por el contenido.

Temas y layouts

Hay dos carpetas que nos var interesar la carpeta themes y la carpeta layouts. Generalmente layouts estará vacía y cuando se tenga que crear un sitio, se tomarán los archivos de themes y se usará el tema que se haya seleccionado. Puede ocurrir que deseemos que independientemente del tema a utilizar, se use una determinada configuración para la página de inicio (por ejemplo), podemos entonces crear nuestra página de inicio en layouts que se usará independientemente del tema que se vaya a poner por defecto.

Plantillas principales de Hugo

Tenemos la plantillas:

  • Single: Representa cómo se va a dibujar una entrada o un elemento simple de contenidos
  • List: Representa cómo se va a dibujar una lista de contenidos.
  • Homepage: Es la página de inicio de nuestro sitio.

Empecemos por la página de inicio, la vamos a entrar en el directorio “themes/nuestro-tema/index.html”. Probad a editarla y veréis cómo se modifica la página de inicio de vuestro sitio.

Según el tema, también deberéis tocar ciertos parámetros de la configuración para cambiar ciertos elementos del tema.

Pero antes de continuar vamos a ver las posibilidades de las plantillas de Go.

Plantillas de Go

Variables

Hugo usa las plantillas del lenguaje Go para procesar el texto html de forma muy rápida. Como ya se ha dicho, las plantillas van entre los símbolos {{ }}. Así, por ejemplo, para obtener el valor de una variable ya definida se pondría:

<!DOCTYPE html>
<html>
<body>
  {{ variable }}
</body>
</html>

Las variables que define Hugo, se pueden encontrar en:

http://gohugo.io/templates/variables/

Para definir el valor de una variable también se puede usar el símbolo $ delante de la variable:

{{ $variable := "Hola mundo" }}

Después se obtiene su valor:

{{ $variable }}

Hugo también permite usar funciones, las funciones predefinidas se pueden encontrar en:

http://gohugo.io/templates/functions/

Para usar una función simplemente se la llama por su nombre:

{{ función }}

Para pasar argumentos a una función, se ponen los argumentos separados por espacios:

{{ add 1 2}}

La función add suma dos valores, en este caso devolverá 3.

Iteraciones

Las plantillas de Hugo permiten iterar entre los elementos de una array. Para ello se usará “range”. Por ejemplo, para listar todos los elementos de un array:

{{ range $elemento := array }}
    {{ $elemento }}
{{ end }}

Vamos a verlo funcionar, se abre el archivo index.html, dentro de nuestra carpeta themes/tema, e introducimos:

{{ range $pagina := .Data.Pages }}
    Títulos de páginas: {{ $pagina.Title }}<br/>
{{ end }}

Ahora al generar el sitio veremos el contenido que se ha introducido al ejecutar “range”.

Se puede también acceder por contexto:

{{ range array }}
    {{ . }}
{{ end }}

En el ejemplo que estábamos manejando:

{{ range .Data.Pages }}
    Títulos de páginas: {{ .Title }}<br/>
{{ end }}

Por último, se pueden usar mapas, para iterar en el mapa se puede usar la siguiente construcción:

{{range $índice, $elemento := array}}
    {{ $índice }}
    {{ $elemento }}
{{ end }}

En nuestro ejemplo:

{{ range $index, $page := .Paginator.Pages }}
    {{ $index }}
    {{ $page.Title }} <br/>
{{ end }}

Condicionales

La estructura if está soportada por la plantillas de Go. Por ejemplo:

{{ if lt 2 3 }}
    Cierto
{{ end }}

que significa si 2 es menor que 3 escribe “Cierto”.

Disponemos de los comparadores:

  • eq Devuelve verdadero si arg1 == arg2
  • ne Devuelve verdadero si arg1 != arg2
  • lt Devuelve verdadero si arg1 < arg2
  • le Devuelve verdadero si arg1 <= arg2
  • gt Devuelve verdadero si arg1 > arg2
  • ge Devuelve verdadero si arg1 >= arg2

Se puede usar and y or para añadir nuevas condiciones, pero hay que tener en cuenta que en la plantillas de Go los argumentos van siempre detrás de la función:

{{ if and (lt 2 3) (gt 3 2) }}
    Cierto
{{ end }}

Por supuesto, la estructura if-else también se puede usar:

{{ if lt 3 2 }}
    False
{{ else }}
    Cierto
{{ end }}

Else if:

{{ if lt 3 2 }}
    False
{{ else if gt 3 2 }}
    Cierto
{{ end }}

Se puede usar not para negar una condición:

{{ if not lt 3 2 }}
    Cierto
{{ end }}

Contextos

A veces tenemos que hacer referencia a objetos dentro de otros objetos y hay que escribir mucho código. Una forma de hacer esta tarea más cómoda es usando with. En el siguiente ejemplo, cada vez que nos refiramos a . dentro de la estructura with, nos estaremos refiriendo a “.Params.title”:

{{ with .Params.title }}
    <h4>{{ . }}>
{{ end }}

Tuberías

Se tiene algo similar a las tuberías UNIX, por ejemplo, supongamos la siguiente operación matemática:

{{ add 5 (add 3 2) }}

Se podría escribir de la siguiente forma:

{{ add 3 2 | add 5 }}

Como se puede ver el resultado de la suma 3+2 se pasa como último argumento de la siguiente operación “add 5”.

Se pueden encadenar varias tubería:

{{ add 3 2 | add 5 | add 4}}

Uso del operador . en contextos

El operador {{ . }} siempre se refiere al contexto actual. Nos sirve para llamar a variables y a varibles dentro de variables (“.Params.title”). Dentro de un bucle {{ . }} se referirá al valor del elemento actual. Si es necesario acceder al contexto global, se puede usar $., por ejemplo:

{{ range .Data.Pages }}
    Títulos de páginas: {{ .Title }}
    {{ $.Site.Title }} <br/>
{{ end }}

Includes

Se puede incluir un archivo dentro de otro. Por ejemplo, podríamos tener en una archivo la cabecera que queremos que aparezca en todas las páginas web de nuestro sitio. En otro archivo el pie de página. En cada página que escribamos, podemos incluirlos usando:

{{ partial "cabecera" . }}

Texto de la página

{{ partial "pie" . }}

De forma automática Hugo incluirá el pie y la cabecera en la página. Si hacemos una modificación en la cabecera, todas las páginas en las que hayamos incluido la cabecera, recibirán la actualización.

Para incluir archivos podemos usar el comando partial:

{{ partial "archivo" contexto }}

El archivo debe estar localizado en el directorio layout/partials. El contexto se refiere a las variables a las que tendrá acceso el archivo incluido, normalmente acceden a “.”.

Tenemos otra forma de incluir archivos usando template:

{{ template "archivo" contexto }}

La diferencia se encuentra en que el archivo a incluir deberá estar en layout. La documentación de Hugo recomienda usar partial.

Si exploráis los temas de Hugo vais a ver buenos ejemplos del uso de partial.

Existe otra forma de incluir plantillas, la función “.Render”. Para introducir contenidos con “.Render” sólo hay que incluir el nombre de la plantilla a utilizar. Por ejemplo, para ver la plantilla “summary.html”:

{{ .Render "summary"}}

Eliminando espacios en blanco

Imaginad que el comando “.Title” devuelva un título con espacios en blanco y saltos de línea antes y después, por ejemplo:

<h1>{{ .Title }}</h1>

e imaginad que la salida final fuera:

<h1>
    Ejemplo de título
        </h1>

Esta salida no es elegante ni cómoda de leer a la hora de editar código.

Usando el operador {{- -}} se pueden eleminar estos espacios:

<h1>{{- .Title -}}</h1>

La salida final sería:

<h1>Ejemplo de título</h1>

Paso de parámetros a las pantillas

Hugo tiene predefinidas una serie de variables que pueden ser útiles:

http://gohugo.io/templates/variables/

A través de los archivos de configuración o a través de metadatos, se pueden pasar parámetros, definidos por el usuario, a las plantillas. Supongamos que se define la sección params en el archivo “config.toml”. Dentro de esta sección definimos las variables que necesitamos, por ejemplo:

baseurl = "http://localhost:1313"
languageCode = "es"
title = "Ejemplo de nuevo sitio"

[params]
ejemplo = "Ejemplo de valor definido"

Dentro de uno de los archivos del tema podremos introducir:

{{ .Site.Params.Ejemplo }}

y allí obtendremos el valor de la variable.

De forma similar se pueden definir variables en la cabecera de las entradas. Por ejemplo, si se tiene la entrada “hola-mundo.md”, se podría introducir la variable “Fecha”:

+++
date = "2017-04-07T01:04:36+02:00"
title = "hola mundo"
Fecha = true

+++

Hola mundo **esto** es un ejemplo.

Ahora se podría ir a la parte del tema correspondiente y hacer que si Fecha es true, se muestre la fecha de esta entrada:

{{ if .Params.Fecha }}
    {{ .Date.Format .Site.Data.Formats.date }}
{{ end }}

Como se puede ver usando “.Params.parámetro” se puede acceder al valor de la variable.

Para terminar

Hasta aquí esta breve introducción a los temas Hugo. Un par de recomendaciones:

La primera, ver la documentación oficial de Hugo:

https://gohugo.io/templates/go-templates/

Por otro lado es bueno bajarse un tema y explorarlo y modificarlo. Veremos que se usan cosas como “.Render” que llama a alguna plantilla para mostrar los contenidos. Para no volvernos locos buscando los archivos se recomenda usar los comandos de UNIX grep y find:

Con grep buscaremos los archivos que contengan algún tipo de texto que nos interese:

grep -Re 'texto a buscar'

Por otro lado find nos ayuda a buscar archivos por su nombre:

find . -name "nombre del archivo"

En el nombre del archivo se pueden introducir wildchars como son el * y la ? que nos ayudan a buscar los archivos de forma más cómoda.


Liher Sanchez

Liher Sanchez
El blog de Liher

Como desactivar el CDROM en los repositorios de Debian y Ubuntu

Este es uno de los muchos artículos que voy a escribir a partir de ahora sobre Debian, en concreto de la rama Testing, actualmente Stretch o Debian 9. Quiero ir detallando en cada uno de ellos los pasos que voy dando para poner a punto esta magnífica distribución Linux y como ir resolviendo los problemas que nos podemos ir encontrando durante el proceso. En mi caso, después de instalar Debian 9 en mi disco duro, una de las primeras cosas que hice fue actualizar el sistema. Durante el proceso de instalación tenemos la opción de configurar APT y conectar con un servidor para que al terminar de instalar Debian el sistema esté completamente actualizado, por lo tanto es algo que no es necesario en ese momento, pero es una costumbre que tengo. Tarde o temprano tendremos que hacerlo, y lo recomendable es que sea a menudo, por lo que este problema nos surgirá pronto. El tema es que cuando vayamos a actualizar nuestro recientemente instalado Debian mediante la Terminal nos saldrá un error diciendo que no encuentra el CDROM con el que lo instalamos. Esto es lo que os voy a mostrar como corregir, vamos a ver como desactivar el CDROM en la lista de repositorios que Debian tiene configurados por defecto, también veremos como hacerlo en Ubuntu, aunque en este caso queda desactivado después de instalar.

Os voy a poner en escena. Lo que yo hice fue instalar Debian 9, cuando fui a entrar por primera vez ingresé mi nombre de usuario y mi contraseña y me encontré con el escritorio. Me puse a configurar el panel de XFCE, tienes la opción de usar la configuración predeterminada pero yo prefiero hacerlo desde cero a mi gusto. Este es un proceso que apenas lleva 5 minutos y es muy fácil de hacer. Una vez terminado mi escritorio luce tal que así

 

escritorio debian 9 XFCE recien instalado

 

Como podéis ver es un escritorio bastante sencillo, ya lo iré tuneando :D. Lo siguiente que hice fue abrir una Terminal para comprobar que el sistema estuviese actualizado. Como no he configurado todavía el “sudo”, y no se si lo haré, primero hay que entrar como “root” o superusuario con el siguiente comando:

su

Entonces escribí la contraseña que hay que establecer para dicho usuario durante el proceso de instalación de Debian y seguidamente escribí esto:

apt-get update

Con este comando Debian mira los repositorios que tenga configurados para ver si hay alguna versión nueva de todo lo que tenemos instalado. Al hacer dicha revisión me apareció lo siguiente:

 

error en los repositorios de Debian 9

 

Como podéis ver aparecen muchas lineas con errores. Cuando tecleamos “apt-get update” lo que os debería aparecer es esto:

 

apt correcto con Debian 9

 

En esta imagen podéis ver que solo se muestran dos repositorios, son las lineas 3 y 4, las que empiezan por “Obj” y que no hay ningún error. Para desactivar el CDROM en los repositorios de Debian lo que tenemos que hacer es teclear el siguiente comando en la Terminal:

nano /etc/apt/sources.list

Con este comando abrimos el editor de texto Nano en la Terminal con la lista de repositorios que está usando Debian 9 en ese momento y veremos algo así:

 

repositorios sin CDROM en Debian

 

En vuestro caso no estará exactamente igual ya que el CDROM todavia no está desactivado. Para desactivarlo tenemos dos opciones, una es borrar todo menos las lineas 4, 5, 6 y 7, las que empiezan por “deb”, y la otra opción es ponerlo como está en la imagen, que es lo que yo hice, puse un “#” y luego “CDROM de instalación desactivado” en la primera linea, esto es un comentario que Debian pasa por alto y que solo sirve como información para la persona que ve el fichero. A las dos lineas siguientes también les puse un “#” delante, esas dos lineas son el CDROM que Debian tiene como uno de los repositorios a mirar para actualizaciones o instalaciones de programas nuevos, al ponerles el “#” Debian las pasa por alto, de cara al sistema operativo es como borrarlas. Una vez hechos estos cambios pulsamos la tecla CTRL + o para guardar, nos pregunta el nombre del fichero, pulsamos la tecla Enter para que mantenga el mismo nombre y después pulsamos CTRL + x para salir del Nano. Finalmente, en la Terminal tecleamos “exit” para dejar de usar “root” y listo.

De esta forma tan sencilla es como podemos desactivar el CDROM en los repositorios de Debian y Ubuntu. En Ubuntu el procedimiento sería el mismo con la salvedad de que ya viene hecho después de la hacer la instalación, por lo que no tenemos que hacerlo manualmente.

Un saludo a todos.

Gaspar Fernández

Gaspar Fernández
Poesía Binaria

Cómo obtener información de salud de tu sistema Linux o tu servidor en C y C++ (I. Memoria)

Es algo necesario para el buen funcionamiento de nuestras aplicaciones. Para añadir robustez a nuestros sistemas, haciendo que éstos se comporten de manera adecuada en situaciones imprevistas. Por ejemplo, si necesitamos crear un archivo y añadir cierta información, podemos, a priori, comprobar que el dispositivo en el que vamos a escribir tiene suficiente espacio libre, lo que nos puede ahorrar suplicios si los ficheros son demasiado grandes. También deberíamos ser capaces de comprobar que un disco de red está conectado antes de trabajar con él y, en muchos casos, anticiparnos a largas esperas y bloqueos por parte del sistema operativo. O incluso tomar una decisión ante una tarea intensiva que no es prioritaria comprobando primero cómo de ocupado está nuestro sistema.

La serie de posts sobre salud del sistema

El post me ha salido enorme por lo que he decidido dividirlo en varias partes que se publicarán una cada dos semanas. Como siempre, voy intercalando posts sobre otras temáticas relacionadas, para no estar siempre hablando de lo mismo.
Si sois impacientes y queréis ver mucha información y resultados con código, podéis ver este proyecto en GitHub (linuxmon) donde se tratan muchos de estos temas. Aunque, en esta serie de posts me gustaría completar algo más la información obtenida y, estará todo explicado.

C y C++ en los ejemplos

Muchos ejemplos son básicamente acceso a ficheros o utilización de funciones de C de bibliotecas de Linux y POSIX. Aunque he utilizado C++ para facilitar un poco la salida de datos y pelearme un poco menos con la memoria en algunos casos utilizando string, vector, map y alguna cosa más. De todas formas, para aclaraciones sobre cómo hacer todo esto en C puro, podéis preguntar en los comentarios.

Para el código C++, he utilizado algunas de las novedades disponibles a partir de la especificación de 2011 que, como ya tiene 6 años, considero que todos podremos compilarlo.

Por tanto, para compilar estos ejemplos, debemos hacer:

g++ -o ejecutable fuente.cpp -std=c++11 -lpthread

La biblioteca pthread la necesito sólo para un par de ejemplos en los que utilizo hilos y alguna que otra guarrada de la que no me siento orgulloso, pero que a lo mejor puede resultar de ayuda para alguien.

Algunas funciones que nos serán de ayuda

Está claro que como programadores, no es difícil pelearnos nos bytes, por ejemplo para comprobar que el espacio libre es mayor a un tamaño determinado. Lo malo es que imprimir en pantalla números más o menos grandes (del orden de miles de millones) para expresar tamaños puede resultar difícil de leer, así que utilizaremos funciones como size() para obtener el tamaño en formato humano.

De forma parecida, con el objetivo de simplificar nuestro código, la función extractFile() leerá un archivo en su totalidad y lo almacenará en un buffer.
Ambas funciones las pongo aquí junto con un ejemplo de uso:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <string>
#include <unistd.h>                         /* Utilidades UNIX */
#include <fcntl.h>                          /* Control de archivos */

/** Humanize size */
std::string size(long double size, int8_t precision=3)
{
    static const char* units[10]={"bytes","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb","Bb"};
    char temp[32];
    char format[10];

    int i= 0;

    while (size>1024)
        {
            size = size /1024;
            i++;
        }

    snprintf(format, 10, "%%.%dLf%%s", precision);
    snprintf(temp, 32, format, size, units[i]);

    return std::string(temp);
}

/** Extract a whole file into a string  */
std::string extractFile(const char *filename, size_t bufferSize=512)
{
    int fd = open(filename, O_RDONLY);
    std::string output;

    if (fd==-1)
        return "";      /* error opening */

    char *buffer = (char*)malloc(bufferSize);
    if (buffer==NULL)
        return "";      /* Can't allocate memory */

    int datalength;
    while ((datalength = read(fd, buffer, bufferSize)) > 0)
        output.append(buffer, datalength);

    close(fd);
    return output;
}

using namespace std;

int main(int argc, char* argv[])
{
    cout << size(1023339229) << endl;
    cout << extractFile("utils.cpp")<<endl;
    return 0;
}

En ambas funciones podría haber utilizado utilidades de C++ para la lectura de ficheros, o para transformar los números en cadena de caracteres y presentar la información. En este caso no lo hice así por cuestión de velocidad, ya que pienso utilizar estas funciones muchas veces y necesito que se ejecuten bien en sistemas pequeños. En mis pruebas, incluso con la optimización de compilador, he conseguido que estas funciones se ejecuten entre un 40% y un 60% más rápido. Y es normal, las bibliotecas de streams de C++ son muy complejas, no tendríamos limitación por tamaño de cadenas, por ejemplo, para el caso de size(). Y en el caso de extractFile(), utilizo directamente las funciones de unistd. Están más cerca del sistema operativo y se comportan más rápido que las de C y mucho más que las de C++.

Pongo aquí una versión en C puro de la función size() que también utilizaré en algunos ejemplos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
char* size(char* storage, long double size, int8_t precision)
{
    static const char* units[10]={"bytes","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb","Bb"};
    char format[10];

    int i= 0;

    while (size>1024)
        {
            size = size /1024;
            i++;
        }

    snprintf(format, 10, "%%.%dLf%%s", precision);
    snprintf(storage, 32, format, size, units[i]);

    return storage;
}

Información de memoria y uso del sistema: sysinfo()

En Linux, tenemos la función sysinfo() dentro de sys/sysinfo.h, que devuelve en una estructura homómina (struct sysinfo) la siguiente información:

  • long uptime : Segundos desde el arranque del ordenador.
  • unsigned long loads[3] : Carga media en 1, 5 y 15 minutos (que podemos ver con el comando uptime). La carga del sistema está expresada en la medida que diga la constante SI_LOAD_SHIFT, es decir, el 100% de carga podría ser por ejemplo 65536 por lo que para encontrar el % real debemos dividir por ese número.
  • unsigned long totalram : Memoria RAM total
  • unsigned long freeram : Memoria RAM libre
  • unsigned long sharedram : Memoria RAM compartida
  • unsigned long bufferram : Memoria RAM usada en buffers
  • unsigned long totalswap : Memoria SWAP total
  • unsigned long freeswap : Memoria SWAP libre
  • unsigned short procs : Número de procesos en marcha actualmente. Aunque en este caso indica los hilos en ejecución, que serán muchos más.
  • unsigned int mem_unit : Tamaño de la unidad de memoria en bytes

Como ejemplo podemos hacer lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdio.h>
#include <sys/sysinfo.h>
#include <time.h>
#include <stdint.h>

#include <string.h>                         /* strerror() */
#include <errno.h>
#include <stdlib.h>

/** Humanize size */
char* size(char* storage, long double size, int8_t precision)
{
    static const char* units[10]={"bytes","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb","Bb"};
    char format[10];

    int i= 0;

    while (size>1024)
        {
            size = size /1024;
            i++;
        }

    snprintf(format, 10, "%%.%dLf%%s", precision);
    snprintf(storage, 32, format, size, units[i]);

    return storage;
}

void panic(char* error)
{
    fprintf (stderr, "Error: %s (%d - %s)\n", error, errno, strerror(errno));
    exit(-1);
}

int main(int argc, char* argv[])
{
    struct sysinfo si;
    struct tm temptime;     /* Utilizado para presentar uptime en formato humano */
    char temp[32];              /* Cadena temporal para los tamaños. (función size()) */
   
    if (sysinfo(&si) <0)
        panic("No puedo hacer sysinfo");

    localtime_r(&si.uptime, &temptime);

    printf ("Uptime: %ld (%d años, %d meses %d dias %d horas %d minutos %d segundos)\n",
                    si.uptime,
                    temptime.tm_year-70,    /* Los años empiezan en 1970, restamos 70*/
                    temptime.tm_mon,
                    temptime.tm_mday-1,     /* El primer día es el 1 */
                    temptime.tm_hour,
                    temptime.tm_min,
                    temptime.tm_sec);

    printf ("Carga del sistema: %lu %lu %lu (%f %f %f)\n",
                    si.loads[0], si.loads[1], si.loads[2],
                    si.loads[0] / (float) (1<<SI_LOAD_SHIFT),
                    si.loads[1] / (float) (1<<SI_LOAD_SHIFT),
                    si.loads[2] / (float) (1<<SI_LOAD_SHIFT));
    printf ("Procesos corriendo: %d\n", si.procs);
    printf ("Unidad de memoria: %d (%s)\n", si.mem_unit, size(temp, si.mem_unit, 3 ));
    printf ("RAM total: %ld (%s)\n", si.totalram, size(temp, si.totalram*si.mem_unit, 3));
    printf ("RAM free: %ld (%s)\n", si.freeram, size(temp, si.freeram*si.mem_unit, 3));
    printf ("RAM compartida: %ld (%s)\n", si.sharedram, size(temp, si.sharedram*si.mem_unit, 3));
    printf ("RAM buffers: %ld (%s)\n", si.bufferram, size(temp, si.bufferram*si.mem_unit, 3));
    printf ("RAM usada: %ld (%s)\n", si.totalram - si.freeram - si.bufferram,
                    size(temp, (si.totalram - si.freeram - si.bufferram)*si.mem_unit, 3));
    printf ("SWAP total: %ld (%s)\n", si.totalswap, size(temp, si.totalswap*si.mem_unit, 3));
    printf ("SWAP free: %ld (%s)\n", si.freeswap, size(temp, si.freeswap*si.mem_unit, 3));
    printf ("SWAP usada: %ld (%s)\n", si.totalswap - si.freeswap, size(temp, (si.totalswap-si.freeswap)*si.mem_unit, 3));
    printf ("Total high: %ld (%s)\n", si.totalhigh, size(temp, si.totalhigh*si.mem_unit, 3));
    printf ("Free high: %ld (%s)\n", si.freehigh, size(temp, si.freehigh*si.mem_unit, 3));
   
    return 0;
}

En el ejemplo anterior, lo que puede que no quede muy claro es la memoria alta total y libre. Este tipo de memoria se utiliza en sistemas que tienen que dividir la memoria principal para poder acceder a ella correctamente. Como ejemplo, podemos indicar dispositivos con un ancho de bus inferior a la cantidad de memoria a la que pueden acceder, hace unos años era muy común esto, por ejemplo en CPUs de 16bit que necesitaban poder acceder a varios megabytes de RAM (cuando con 16bit no podríamos expresar números mayores de 65535). O, hace algunos años menos, cuando CPUs de 32bit con arquitectura Intel debían acceder a más de 4Gb de RAM, lo que se conocía como PAE o Physical Address Extension. La memoria alta sería aquella a la que no podíamos acceder tan directamente.

Información sobre paginado de memoria

Existen tres funciones más para averiguar:

  • Tamaño de páginas de memoria. getpagesize() o sysconf(_SC_PAGESIZE) como veremos más adelante.
  • Total de páginas en RAM (páginas físicas). get_phys_pages(). Este número de páginas será la cantidad total de memoria entre el tamaño de página.
  • Total de páginas físicas disponibles. get_avphys_pages(). Que debe ser la cantidad de memoria libre entre el tamaño de página.

Vemos un pequeño ejemplo aquí:

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <unistd.h>
#include <sys/sysinfo.h>

int main(int argc, char* argv[])
{
    printf ("Tamaño de página: %d\n", getpagesize());
    printf ("Páginas físicas: %ld\n", get_phys_pages());
    printf ("Páginas físicas disponibles: %ld\n", get_avphys_pages());

    return 0;
}

Más información sobre la memoria: /proc/meminfo

Con el comando anterior vemos mucha información sobre la memoria aunque, no toda la información que nos da Linux. Si hemos curioseado proc veremos que existe el archivo /proc/meminfo con mucha información más. Eso sí, tenemos que parsear el fichero para extraer la información. Afortunadamente no es un fichero físico, sino un vínculo en nuestro sistema de archivos que se actualiza en tiempo real. Y podemos acceder a él como si fuera un archivo, y eso es muy bueno, muy filosofía unix y nos facilita el acceso a la información desde cualquier lenguaje. Aunque ahora vamos a hacerlo en C++ para facilitarnos un poco la vida:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>                         /* Utilidades UNIX */
#include <fcntl.h>                          /* Control de archivos */

/** Humanize size */
std::string size(long double size, int8_t precision=3)
{
    static const char* units[10]={"bytes","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb","Bb"};
    /* Using a char instead of ostringstream precission because it's faster */
    char temp[32];
    char format[10];

    int i= 0;

    while (size>1024)
        {
            size = size /1024;
            i++;
        }

    snprintf(format, 10, "%%.%dLf%%s", precision);
    snprintf(temp, 32, format, size, units[i]);

    return std::string(temp);
}

/** Extract a whole file into a string  */
std::string extractFile(const char *filename, size_t bufferSize=512)
{
    int fd = open(filename, O_RDONLY);
    std::string output;

    if (fd==-1)
        return "";      /* error opening */

    char *buffer = (char*)malloc(bufferSize);
    if (buffer==NULL)
        return "";      /* Can't allocate memory */

    int datalength;
    while ((datalength = read(fd, buffer, bufferSize)) > 0)
        output.append(buffer, datalength);

    close(fd);
    return output;
}

using namespace std;

int main(int argc, char* argv[])
{
    string memInfo = extractFile ("/proc/meminfo");
    if (memInfo.empty())
        {
            cerr << "Error al leer información"<< endl;
            terminate();
        }

    stringstream ss (memInfo);
    string unit;
    string name;
    unsigned long num;
    ss >> name >> num >> unit;
    while (ss.good())
        {
            name.erase(name.size()-1, 1);
            cout << name<< " -> " << size(num*1024, 3)<<"\n";
            ss >> name >> num;
            ss.ignore(10, '\n');            /* Eliminamos la unidad o hasta el salto de línea */
        }

    return 0;
}

Además, si queremos, podemos crear una función que almacene todo en un mapa de C++ con lo que podremos acceder muy fácilmente a cada uno de los elementos leidos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <unistd.h>                         /* Utilidades UNIX */
#include <fcntl.h>                          /* Control de archivos */

/** Humanize size */
std::string size(long double size, int8_t precision=3)
{
    static const char* units[10]={"bytes","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb","Bb"};
    /* Using a char instead of ostringstream precission because it's faster */
    char temp[32];
    char format[10];

    int i= 0;

    while (size>1024)
        {
            size = size /1024;
            i++;
        }

    snprintf(format, 10, "%%.%dLf%%s", precision);
    snprintf(temp, 32, format, size, units[i]);

    return std::string(temp);
}

/** Extract a whole file into a string  */
std::string extractFile(const char *filename, size_t bufferSize=512)
{
    int fd = open(filename, O_RDONLY);
    std::string output;

    if (fd==-1)
        return "";      /* error opening */

    char *buffer = (char*)malloc(bufferSize);
    if (buffer==NULL)
        return "";      /* Can't allocate memory */

    int datalength;
    while ((datalength = read(fd, buffer, bufferSize)) > 0)
        output.append(buffer, datalength);

    close(fd);
    return output;
}

std::map<std::string, unsigned long> linuxMemory()
{
    std::map<std::string, unsigned long> out;
   
    std::string memInfo = extractFile ("/proc/meminfo");
    if (memInfo.empty())
        {
            std::cerr << "Error al leer información\n";
            std::terminate();
        }

    std::stringstream ss (memInfo);
    std::string unit;
    std::string name;
    unsigned long num;
    ss >> name >> num >> unit;
    while (ss.good())
        {
            name.erase(name.size()-1, 1);
            out[name] = num;
            ss >> name >> num;
            ss.ignore(10, '\n');
        }
    return out;
}

using namespace std;

int main(int argc, char* argv[])
{
    for (auto d : linuxMemory())
        {
            std::cout << "["<<d.first << "] : "<<d.second<<"\n";
        }
    return 0;
}

Memoria utilizada por nuestro programa

Aunque trataremos el tema en profundidad en un futuro post, podemos averiguar la memoria total del programa, tamaño del código, datos y pila leyendo el fichero /proc/self/statm, también podríamos leer el fichero /proc/self/stat (que analizaremos más adelante) o incluso /proc/self/status que deberemos parsear como /proc/meminfo . Por ahora podemos quedarnos con lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <unistd.h>                         /* Utilidades UNIX */
#include <fcntl.h>                          /* Control de archivos */

/** Extract a whole file into a string  */
std::string extractFile(const char *filename, size_t bufferSize=512)
{
    int fd = open(filename, O_RDONLY);
    std::string output;

    if (fd==-1)
        return "";      /* error opening */

    char *buffer = (char*)malloc(bufferSize);
    if (buffer==NULL)
        return "";      /* Can't allocate memory */

    int datalength;
    while ((datalength = read(fd, buffer, bufferSize)) > 0)
        output.append(buffer, datalength);

    close(fd);
    return output;
}

using namespace std;

int main(int argc, char* argv[])
{
    std::string memInfo = extractFile ("/proc/self/statm");

    if (memInfo.empty())
        {
            std::cerr << "Error al leer información\n";
            std::terminate();
        }
    unsigned long size,
        resident,
        share,
        text,
        lib,
        data,
        dt;
   
    std::stringstream ss (memInfo);
   
    ss >> size >> resident >> share >> text >> lib >> data >> dt;

    cout << "Tamaño total: "<<size<<"\n";
    cout << "Tamaño residente: "<<resident<<"\n";
    cout << "Páginas compartidas: "<<share<<"\n";
    cout << "Tamaño de código: "<<text<<"\n";
    cout << "No usado: "<<lib<<"\n";
    cout << "Datos + Pila: "<<data<<"\n";
    cout << "No usado: "<<dt<<"\n";
   
    return 0;
}

Los tamaños vienen expresados en páginas, por lo que para extraer la información en bytes debemos multiplicar el valor obtenido por el tamaño de las páginas (el valor que nos devuelve getpagesize()). En Linux 2.6 o superior vemos que los valores de lib y de dt valen siempre 0, pero el sistema sigue utilizándolos para garantizar la retrocompatibilidad con programas más antiguos. Si queremos hacer este parseo del archivo en C puro podemos utilizar sscanf() que también nos dará muy buen resultado.

Siguiente post

Hablaremos de la CPU, definiciones del sistema, como el tamaño de página y cosas así que pueden resultar interesantes y utilización de recursos por parte de nuestras aplicaciones. Todo esto, a partir del 1 de mayo.

Foto principal: William Stitt

The post Cómo obtener información de salud de tu sistema Linux o tu servidor en C y C++ (I. Memoria) appeared first on Poesía Binaria.

Domingo 16 de abril de 2017

David González

David González
Blog Bitix

Contenedores en Docker Swarm con volúmenes de datos persistentes usando REX-Ray y VirtualBox

Salvo que un servicio sea sin estado o stateless los contenedores de Docker necesitan persistir datos y que estos sobrevivan a su terminación, como es el caso de un contenedor de una base de datos. Además en un cluster de nodos Docker hay que tener en cuenta que los datos deben estar accesibles para todos los nodos ya que un contenedor que usase los datos podría ser lanzado en cualquiera de ellos. REX-Ray es un sistema de almacenamiento en red que cubre estas necesidades, es simple de instalar, configurar y de iniciar. En el artículo muestro un ejemplo usando REX-Ray junto con Docker Swarm y VirtualBox.

Docker

Los contenedores de datos son efímeros, se crean y se destruyen y con ellos los datos que tuviesen en su sistema de archivos de modo que cualquier dato que queramos que sobreviva a la vida del contenedor ha de almacenarse de forma externa, este es el caso de los datos de una base de datos como PostgreSQL o MongoDB. Además usando Docker Swarm se plantea el problema de que hay varios nodos formando un cluster por lo que los datos han de estar accesibles independientemente del nodo en el que sea iniciado el contenedor que los utilice y significa que los datos no pueden estar almacenados en el nodo ya que un contenedor podría ser iniciado en cualquiera de ellos.

Así que los contenedores iniciados en un cluster de Docker Swarm que usen datos persistentes necesitan un sistema de almacenamiento en red externo a los contenedores y nodos. Una de las opciones disponibles es REX-Ray que ofrece una configuración sencilla y múltiples proveedores de computación entre las que están las más populares como Amazon EC2, Digital Ocean, Google Compute Engine, Azure e incluso VirtualBox.

En el siguiente ejemplo uso un cluster de nodos Docker, VirtualBox y REX-Ray para proporcionar volúmenes de datos persistentes para un contenedor que tiene una base de datos postgres basándome en el artículo previo Crear un cluster de contenedores Docker donde explicaba como crear un cluster de nodos con Docker Swarm.

Para la integración entre VirtualBox y REX-Ray hay que iniciar primero un servidor en el host que permite a REX-Ray hacer llamadas remotas a VirtualBox para que gestione los volúmenes de datos.

Si hay un firewall hay que permitir el tráfico para el puerto 18083, en mi caso que uso ufw creando la siguiente regla.

Con el cluster creado debemos instalar y configurar REX-Ray en cada uno de los nodos ejecutando varios comandos, un comando instala REX-Ray, otro crea el archivo de configuración en /etc/rexray/config.yml y finalmente otro inicia el servicio de REX-Ray. Algunas opciones que se indican en el archivo de configuración de REX-Ray es la ubicación en el host donde se guardan los volúmenes con el parámetro volumePath.

Instalación de REX-Ray en nodos de Docker Swarm con VirtualBox

Para probar la persistencia de datos usaré un stack iniciado de la misma forma que en artículo Iniciar un stack de servicios en un cluster de Docker Swarm pero con un contenedor de postgres que guarda los datos en un volumen de REX-Ray en /var/lib/postgresql/data. Para iniciar el stack el custer de Docker Swarm uso un archivo de Docker Compose con la definición del stack en formato YAML.

En la siguiente captura de pantalla se observa en que nodo ha sido iniciado el contenedor de postgres y que identificativo se le ha asignado.

Deploy del stack de postgres

En el stack el volumen de datos postgres está declarado y creado de forma externa. Usando VirtualBox con REX-Ray en el host o anfitrión se crea un archivo que contiene los datos del volumen. Al listar los volúmenes de datos además de los creados postgres y app están los de los discos duros de cada uno de los nodos identificados como disk.vmdk. El parámetro opt=size=5 indica que el volumen de datos es de una tamaño de 5GiB.

Volúmenes de datos

Para crear algunos datos en la base de datos hay que conectarse al contenedor y lanzar algunas sentencias SQL. Hay que obtener el identificativo del contenedor de postgres, iniciar un proceso bash, realizar la conexión a la base de datos con el cliente psql y lanzar las sentencias SQL.

Destruyendo el stack y volviéndolo a arrancar posiblemente Docker Swarm iniciará el contenedor en otro nodo del cluster pero los datos seguirán estando presentes en la base de datos postgres, se puede comprobar iniciando una nueva sesión bash en el nuevo contenedor, iniciando el cliente de psql y lanzando la consulta select de SQL o con el comando \dt para obtener las tablas de la base de datos, \d+ company para obtener una descripción de la tabla y la consulta SQL SELECT * FROM company;.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub.

David González

David González
Blog Bitix

Escalar y actualizar un servicio de un cluster de Docker Swarm

Ya tenemos un cluster formado por varios nodos con algún servicio ejecutándose en el cluster de Docker Swarm. Si surge la necesidad los servicios del cluster se pueden escalar cambiando el número de instancias de contenedores que forma el servicio para atender las necesidades computacionales o para ofrecer el servicio a más usuarios. Por otro lado, pasado un tiempo muy posiblemente se publicará una nueva imagen de los contenedores, el servicio se puede actualizar para que los contenedores utilicen esa nueva imagen.

Docker

Una vez que ya hemos creado un cluster de nodos con Docker Swarm y hemos desplegado algunos servicios ya sea directamente mediante comandos para crear servicios o mediante un stack con un archivo similar a un Docker Compose al cabo de un tiempo necesitaremos hacer otras operaciones. Dos de esas operaciónes básicas son escalar hacia arriba o hacia abajo un servicio cambiando el número de instancias de contenedores desplegadas o actualizar la imagen que utilizan los servicios por otra diferente posiblemente más nueva.

En la documentación de Docker están detallados y comentados los comandos para escalar un servicio. Por ejemplo, en el cluster de ejemplo formado por tres nodos, uno con el rol de manager y otros dos como worker, ejecutándose en VirtualBox y desplegando un servicio para el servidor nginx con inicialmente una réplica o instancia podemos escalar el servicio para que se cree alguna instancia o contenedor más del servicio con el siguiente comando docker service scale.

Al igual que cuando se crea un contenedor para un servicio en el cluster Docker Swarm si no se indica alguna restricción decidirá en qué nodos se crean las nuevas instancias o contenedores del servicio.

Servicio de nginx antes y después de escalarlo
Escalado del servicio de nginx

Por otro lado, una vez desplegados en un cluster algunos servicios llegará el momento en que queramos actualizar algún parámetro del servicio, uno de ellos será probablemente la imagen del servicio cuando se publique una nueva. En la página de documentación Aplicando actualizaciones a un servicio está explicada esta funcionalidad y los comandos junto con sus opciones que hay que utilizar.

En el ejemplo al crear el cluster se usa la última imagen de docker para nginx, en un entorno de producción es más recomendable establecer una versión en concreto para evitar que la imagen que se usa no varía desde que se prueba hasta que se despliega. El siguiente script actualiza la imagen a la versión nginx:1.10-alpine en todas las réplicas del servicio de nginx en el cluster.

Actualización de la imagen del servicio de nginx

Docker Swarm realiza el proceso de actualización siguiendo los siguientes pasos:

  • Detiene el primer contenedor o tarea a actualizar.
  • Programa la actualización del contenedor o tarea detenida.
  • Inicia una nueva tarea actualizado.
  • Si la tarea actualizada retorna su estado como RUNNING se espera un tiempo determinado y se inicia el proceso de actualización de una nueva tarea.
  • Si, en cualquier momento durante la actualización, una tarea retorna su estado como FAILED, se detiene la actualización.

Por defecto, el planificador actualiza las tareas o contenedores del servicio de uno en uno. Con la opción –update-parallelism se especifica el número de tareas del servicio que se actualizan simultáneamente. La opción –update-delay especifica el tiempo de espera desde que se actualiza la tarea de un servicio y la siguiente. Se puede describir como una combinación de segundos, minutos o horas, de modo que 1m30s indica una espera de 1 minuto y 30 segundos.

En los archivos en formato YAML de los stacks de Docker Compose hay una sección en cada servicio en el que se indica el número de contenedores que se desea que esté formado el servicio así como las opciones de paralelismo y tiempo de espera entre actualización. Para actualizar el stack basta con hacer de nuevo el deploy, ya sea la imagen usada, el número de réplicas u otros parámetros.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub.

Sábado 15 de abril de 2017

Tutorial de Rocket, echa a volar tus webapps con Rust

Previamente ya hemos hablado de Iron como un web framework para Rust. Sin embargo desde que escribí ese post ha surgido otra librería que ha ganado mucha popularidad en poco tiempo. Se trata de Rocket. Un web framework que propone usar el rendimiento que ofrece Rust sin sacrificar la facilidad de uso de otros lenguajes.

Rocket lleva las pilas cargadas

A diferencia de Iron, Rocket incluye bastantes prestaciones por defecto con soporte para:

  • Plantillas
  • Cookies
  • Formularios
  • JSON
  • Soporte para rutas dinámicas

Un “Hola Mundo”

Rocket necesita una versión nightly del compilador de Rust. Una vez lo tengas creamos una aplicación con Cargo.

cargo new --bin rocket_app

Ahora modificamos el fichero Cargo.toml generado en la carpeta rocket_app para añadir las siguientes dependencias:

rocket = "0.2.4"
rocket_codegen = "0.2.4"
rocket_contrib = "*"

Editamos el archivo src/main.rs para que se parezca algo a esto:

#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "El cohete ha despegado"
}

fn main() {
    rocket::ignite().mount("/",routes![index]).launch();
}

Con esto iniciamos Rocket y dejamos a la función index que gestione las peticiones GET encaminadas a /. El servidor devolverá El cohete ha despegado.

Ahora si ejecutamos cargo run veremos algo similar a esto:

Vemos que el servidor ya está escuchando en el puerto 8000 y está usando todos los cores (en mi caso 4) del ordenador.

Configurar Rocket

Rocket dispone de varias configuraciones predeterminadas que afectan a su funcionamiento. Para alternar entre las configuraciones debemos usar variables de entorno y para modificar las configuraciones en sí debemos usar un fichero llamado Rocket.toml.

Las configuraciones por defecto son: dev (development), stage (staging) y prod (production). Si no indicamos nada, Rocket se inicia con la configuración dev. Para arrancar con la configuración de producción modificamos el valor de ROCKET_ENV.

ROCKET_ENV=prod cargo run --release

Sería el comando para arrancar Rocket en modo producción. En el archivo Rocket.toml se puede modificar cada configuración, estableciendo el puerto, el número de workers y parámetros extra pero no vamos a entrar en ello.

Rutas dinámicas

Rocket soporta rutas dinámicas. Por ejemplo, si hacemos GET  /pelicula/Intocable podemos definir que la parte del nombre de la película sea un parámetro. Esto hará que la función encargada de /pelicula/Intocable y de /pelicula/Ratatouille sea la misma.

#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate rocket;

#[get("/pelicula/<pelicula>")]
fn pelicula(pelicula: &str) -> String {
    format!("Veo que te gusta {}, a mi también!",pelicula)
}

#[get("/")]
fn index() -> &'static str {
    "El cohete ha despegado"
}

fn main() {
    rocket::ignite().mount("/",routes![index,pelicula]).launch();
}

Los argumentos de la función son los parámetros de la petición GET. ¿Qué pasa si no concuerda el tipo de la función con lo que se pasa por HTTP? Nada. Sencillamente Rocket ignora esa petición, busca otra ruta (puede haber sobrecarga de rutas) y si encuentra otra que si satisfaga los parámetros será esa la escogida. Para especificar el orden en el que se hace la sobrecarga de rutas puede usarse rank. En caso de no encontrarse nada, se devuelve un error 404.

POST, subir JSON y formularios

Rocket se integra con Serde para lograr una serialización/deserialización con JSON inocua. Si añadimos las dependencias serde, serde_json y serde_derive al fichero Cargo.toml podemos tener un método que acepete una petición POST solo para mensajes del tipo application/json con deserialización incorporada.

#![feature(plugin)]
#![plugin(rocket_codegen)]

#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate serde_derive;
extern crate serde_json;
extern crate rocket;

use rocket_contrib::{JSON, Value};

#[derive(Serialize,Deserialize)]
struct User{
    name: String,
    email: String
}

#[post("/upload", format="application/json", data="<user>")]
fn upload_user(user: JSON<User>) -> JSON<Value> {
    JSON(json!({
        "status" : 200,
        "message" : format!("Usuario {} registrado con éxito",user.email)
    }))
}

fn main() {
    rocket::ignite().mount("/",routes![upload_user]).launch();
}

Si el JSON no se ajusta a la estructura User simplemente se descarta devolviendo un error 400.

Lo mismo que es posible hacer con JSON puede hacerse con formularios usando el trait FromForm.

#![feature(plugin,custom_derive)]
#![plugin(rocket_codegen)]

#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate serde_derive;
extern crate serde_json;
extern crate rocket;

use rocket_contrib::{JSON, Value};
use rocket::request::{FromForm, Form};

#[derive(FromForm)]
struct User{
    name: String,
    email: String
}

#[post("/upload", data="<user>")]
fn upload_user(user: Form<User>) -> String {
    format!("Hola {}",user.get().name)
}

fn main() {
    rocket::ignite().mount("/",routes![upload_user]).launch();
}

Errores

En Rocket, como es lógico, es posible crear páginas personalizadas para cada error.

#![feature(plugin,custom_derive)]
#![plugin(rocket_codegen)]

#[get("/")]
fn index() -> &'static str {
    "El cohete ha despegado"
}

#[error(404)]
fn not_found() -> &'static str {
    "La página no ha podido ser encontrada"
}

fn main() {
    rocket::ignite().mount("/",routes![index]).catch(errors![not_found]).launch();
}

La lista de métodos que manejan errores hay que pasarla en el método catch de rocket::ignite

Respuestas

Rocket nos permite devolver cualquier cosa que implemente el trait Responder. Algunos tipos ya lo llevan como String, File, JSON, Option y Result. Pero nada nos impide que nuestros propios tipos implementen Responder. Con Responder tenemos el contenido y el código de error (que en la mayoría de casos será 200). En el caso de Result es muy interesante, pues si Err contiene algo que implementa Responder, se devolverá la salida que implemente también, pudiendo así hacer mejores respuestas de error, mientras que si no lo hacen se llamará al método que implemente el error 500 de forma genérica. Con Option, si el valor es Some se devolverá el contenido, si es None se generará un error 404.

#![feature(plugin,custom_derive)]
#![plugin(rocket_codegen)]

#[macro_use] extern crate rocket_contrib;
extern crate rocket;

use rocket::response::{self, Responder, Response};
use std::io::Cursor;
use rocket::http::ContentType;

struct Pelicula{
    nombre: &'static str,
    pais: &'static str
}

impl<'r> Responder<'r> for Pelicula{
    fn respond(self) -> response::Result<'r> {
        Response::build()
        .sized_body(Cursor::new(format!("La película {} se hizo en {}",self.nombre,self.pais)))
        .header(ContentType::new("text","plain"))
        .ok()
    }
}

#[get("/pelicula/<pelicula>")]
fn pelicula(pelicula: &str) -> Result<Pelicula,String> {
    let intocable = Pelicula{
        nombre: "Intocable",
        pais: "Francia"
    };
    let madMax = Pelicula{
        nombre: "Mad Max",
        pais: "Estados Unidos"
    };
    match pelicula {
        "Intocable" => Ok(intocable),
        "Mad Max" => Ok(madMax),
        _ => Err(format!("No existe esa película en nuestra base de datos"))
    }
}

#[get("/")]
fn index() -> Result<String,String> {
    Err(format!("No implementado"))
}

#[error(404)]
fn not_found() -> &'static str {
    "La página no ha podido ser encontrada"
}

fn main() {
    rocket::ignite().mount("/",routes![index,pelicula]).catch(errors![not_found]).launch();
}

Este ejemplo para /pelicula/Intocable devolverá: La película Intocable se hizo en Francia mientras que para /pelicula/Ratatouille dirá No existe esa película en nuestra base de datos.

También es posible devolver plantillas. Rocket se integra por defecto con Handlebars y Tera, aunque no es muy costoso añadir cualquier otra como Maud.

Conclusión

Rocket es un prometedor web framework para Rust, bastante idiomático, que se integra muy bien con el lenguaje. Espero con ansia las nuevas veriones. Es posible que la API cambie bastante hasta que salga la versión 1.0, no obstante así es como ahora mismo funciona.

La entrada Tutorial de Rocket, echa a volar tus webapps con Rust aparece primero en Blog - Adrianistan.eu.

Jueves 13 de abril de 2017

«Limpiando» la memoria utilizada por Firefox

Un breve artículo sobre Firefox: «limpiar» la memoria que utiliza. Cuando Firefox se utiliza durante mucho tiempo, con muchas pestañas y muchas extensiones, su consumo de memoria inevitablemente crece tomando cada vez más recursos del sistema. Una solución simple y evidente para este problema es recordarse de reiniciar el navegador cada tanto, pero existe otra […]

Miércoles 12 de abril de 2017

Diferencia entre Linux y GNU

Al empezar en el mundo de Linux, mucha gente conoce a Richard Stallman y su concepto de “software libre”, de hecho la mayoría siente “la llamada” de usar un sistema operativo libre y comienza con Linux, pero ¿sabemos qué es exactamente Linux o si totalmente es libre?, ¿sabemos que es GNU?. No es hasta que entramos más en profundidad con las características de un sistema operativo

Lunes 10 de abril de 2017

Pedro L. Lucas

Pedro L. Lucas
Cartas de Linux

Resolviendo el problema de los acentos y las eñes que de repente dejan de funcionar

¿Alguna vez os ha pasado que estabais escribiendo algo en vuestro Linux y los acentos han dejado de funcionar? Pues tiene solución y es sencilla, se llama ibus.

En Ubuntu sólo tenemos que ir a “Configuración del sistema/Soporte de Idiomas” y seleccionar en “Sistema de método de entrada de teclado” la opción ibus. Reiniciamos y… problema resuelto.

¿Y si no tengo esta ventana? Por ejemplo, estoy usando un escritorio LXDE con lo mínimo instalado. Entonces hay que instalar ibus:

sudo apt install ibus

Una vez instalado con la herramienta ibus-setup, lo podemos configurar:

Captura de pantalla de 2017-04-09 17-03-22

Fin.


Domingo 09 de abril de 2017

Pedro L. Lucas

Pedro L. Lucas
Cartas de Linux

Contenidos en Hugo – Parte 3

En esta serie de artículos sobre el gestor de contenidos Hugo, vamos a centrarnos en la creación de los contenidos.

Con el comando:

hugo new

Se pueden introducir nuevas entradas en nuestro sitio web. Por ejemplo:

hugo new eldiario/noticia1.md

Dentro del directorio content, se habrá creado una carpeta llamada “eldiario” y allí dentro un archivo con la extensión “md”, “noticia1.md”.

Ahora con:

hugo new eldiario/noticia2.md

Dentro del directorio eldiario/noticia se habrá creado “noticia2.md”.

Si ahora con el comando:

hugo server --theme=hugo_theme_robust -Dv

Visitamos el sitio web creado, se puede comprobar que aparecen noticia1 y noticia2, y a cada una se les ha asignado la etiqueta “eldiario” (que coincide con el nombre del directorio). Si se hace clic sobre el nombre de la etiqueta, nos mostrará todas las noticias que tengan asignada esta etiqueta (notica1 y noticia2).

Si las comparamos con las taxonomías, en las taxonomías se creaba un menú con las etiquetas que se habían introducido. En el caso de las etiquetas no.

Vamos ahora a introducir una imagen en una de las entradas que hemos creado. Las imágenes las podemos poner en 2 lugares:

  • En la carpeta en la que se introduce la entrada.
  • En la carpeta static.

Por ejemplo, creamos una entrada nueva:

hugo new noticia/noticia1.md

Se creará la carpeta “content/noticia” y dentro de ésta “noticia1.md”.

Ahora ponemos una imagen en “content/notica”, por ejemplo, “imagen1.png”. Si queremos hacer que esta imagen aparezca en la noticia, en el texto de la noticia deberemos poner:


+++
date = "2017-04-09T15:35:01+02:00"
draft = true
title = "noticia1"

+++

En formato markdown
![Esto es una imagen](../imagen.png)

En formato html:
<img src='../imagen.png' />

Si nos fijamos, la referencia a la imagen la hacemos a la carpeta anterior “../imagen.png”.

Si ahora, la imagen la ponemos en la carpeta static, la referencia deberá ser:


+++
date = "2017-04-09T15:35:01+02:00"
draft = true
title = "noticia1"

+++

En formato markdown
![Esto es una imagen](/imagen.png)

En formato html:
<img src='/imagen.png' />

Es decir a “/imagen.png”, los contenidos de static se copian directamente a la raíz del sitio web.

Por último, si en static creamos la carpeta “img” y ponemos la imagen en “static/img”, deberemos poner:


+++
date = "2017-04-09T15:35:01+02:00"
draft = true
title = "noticia1"

+++

En formato markdown
![Esto es una imagen](/img/imagen.png)

En formato html:
<img src='/img/imagen.png' />

Es decir, en la raíz del sitio web se va crear la carpeta “/img” y dentro de ella se copiará la imagen.

Algunos temas soportan imágenes en las cabeceras de las noticias, para ello usamos el parámetro thumbnail en la cabecera del documento:

+++
date = "2017-04-09T15:35:01+02:00"
draft = true
title = "noticia1"
thumbnail = "/imagen.png"

+++

Esta es la noticia 1.

Por último, vamos a dar un repaso a los directorios que se crean cuando se ejecuta el comando “hugo new site” para crear un sitio nuevo:

  • archetypes: Cuando se crea un nuevo contenido con el comando “hugo new”, se añaden al artículo algunas configuraciones por defecto, como el título o la fecha. Aquí se pueden definir las configuraciones por defecto que se van a colocar.
  • config.toml: Es el archivo de configuración del sitio web. Usa el lenguaje TOML, aunque se pueden usar otros como JSON o YAML. En él se definen cosas como el nombre del sitio, el idioma, la URL.
  • content: Aquí se almacenan los contenidos que el usuario almacena en el sitio.
  • data: Se usa para almacenar la configuración que Hugo usa para generar el sitio web.
  • layouts: Indica la forma en la que los contenidos van a ser transformados en un sitio estático.
  • static: Lo podemos usar para almacenar todos los contenidos estáticos del sitio, como imágenes, Javascript, CSS, imágenes,… El contenido se copiará a la raíz del sitio.
  • themes: Son los temas que definen la apariencia que va a tener el sitio web. Se pueden crear e instalar varios temas y cambiar de uno a otro. Hay muchos temas disponibles para ser descargados y modificados.

Jueves 06 de abril de 2017

Liher Sanchez

Liher Sanchez
El blog de Liher

Como ver todos los discos duros y sus particiones en la Terminal de Ubuntu

Hace unos días que dediqué unas 10 GB del segundo disco duro de mi portátil a instalar Debian 9. Tuve un pequeño problema con las particiones ya que en el disco duro que he instalado Debian 9 cree una partición de swap y en el disco que tengo Ubuntu tengo otra. Puede que os parezca una tontería tener dos particiones de swap cuando podía tener solo una y compartirla, pero es una manía que tengo, para mi forma de ver justificada, ya que como Debian y Ubuntu están en discos duros diferentes al tener cada disco su swap solo necesito tener un disco duro funcionando cuando estoy en un Linux u otro, ya que si la swap estuviese en el disco de Ubuntu, al estar usando Debian tendría funcionando los dos discos duros, es un tema de ahorro de energía. El tema es que quería ver todas las particiones de todos los discos para no meter la pata y no recordaba como se hacia en la Terminal. Como siempre recurrí a Google y encontré la solución en un artículo de Desde Linux, al cual os dejo un enlace y os recomiendo visitar:

En dicho artículo tenéis varias formas de hacer lo que os comento, miré todas y las probé y la que mas me ha gustado es usar el siguiente comando:

sudo lsblk -fm

Al poner este comando en la Terminal veremos lo siguiente:

 

discos duros y particiones ubuntu

 

A mi forma de ver es la mejor representación que podemos tener de los discos duros y sus correspondientes particiones en la Terminal. Os explico un poco lo que se ve por si tenéis alguna duda.

Justo debajo del comando se ve en mayúsculas unas palabras que nos están diciendo que es lo que está debajo suyo:

  • NAME: es el nombre del disco duro y, las rayas que salen debajo indican las particiones que tiene cada disco. Por ejemplo, el primero es “sda”, que es el primer disco duro, donde tengo instalado Ubuntu 16.04. Debajo esta “sda1” es la partición en la que esta instalado Ubuntu, es la “/”, yo no tengo la “home” aparte, por lo que esta todo ahí. Luego esta “sda2”, que es una partición extendida, es donde están las unidades lógicas, que en este caso es “sda5”, una partición de swap.
  • FSTYPE: es el tipo de sistema de archivos que tiene cada partición. En la imagen podéis ver que “sda1” es “ext4”, ese el el tipo de sistema de archivos de la partición “/” de Ubuntu. Al lado de “sda5” veis que esta “swap”, esto indica que es una partición de intercambio o swap. Mas abajo esta “ntfs” al lado de “sdb1” que es el segundo disco duro de mi portátil y que tiene una partición de 1 TB con NTFS como sistema de archivos.
  • LABEL: es la etiqueta de la partición, es un nombre que se pone para los usuarios, para que sepamos que tiene, la podemos cambiar a voluntad.
  • UUID: es un identificador, cada partición tiene el suyo.
  • MOUNTPOINT: es el punto de montaje de la partición.
  • NAME: otra vez es el nombre de los discos duros y sus particiones.
  • SIZE: el tamaño de cada disco duro y partición expresado en GB.
  • OWNER: es el dueño de los discos duros y sus particiones.
  • GROUP: es el grupo al que pertenecen.
  • MODE: son las opciones de montaje de cada disco duro o partición.

Quizás os parezca mucha información, pero a mi me ayudó a arreglar el problema que tuve que fue que Debian me cambio el UUID de la partición de swap de Ubuntu y al entrar en Ubuntu no tenia partición de intercambio. Fue algo sencillo arreglarlo, de hecho ya lo había mencionado en otra ocasión en un articulo anterior, os dejo el enlace por si os puede servir de ayuda:

Y ya está, ahora ya podéis ver todas las particiones de vuestros discos duros de un solo vistazo en la Terminal de vuestro Ubuntu.

Un saludo a todos.

Consulta el tiempo sin salir de tu consola

¿Eres un apasionado de la meteorología?, ¿de los que no salen de casa sin mirar el tiempo? o por el contrario ¿eres de los que utiliza Linux porque puedes tener todo dentro de la consola y manejar el mundo sin salir de ella?. En cualquiera de los casos contrarios puede ser que este artículo te interesa ya que vamos a mostrarte cómo consultar la meteorología de tu ciudad, de forma “visual”
José María Morales Vázquez

José María Morales Vázquez
tecnología – Un lugar en el mundo…

Problemas de postgrey y las listas grises con los servidores de correo de outlook y hotmail de Microsoft

correo Hace ya años que contamos por aquí en que consisten las listas grises a la hora de validar como bueno un correo y combatir contra el spam y enseñamos a configurarlas en un servidor con Debian y postfix. Recientemente he tenido muchos problemas con los correos que vienen de servidores de Microsoft (¡como no!) que provocaban retrasos de hasta algunos días o pérdida de correos en algunas ocasiones. Vamos a contar que es lo que ocurre y como solucionarlo.

El problema que tenemos con los servidores de correo de Microsoft es que el reintento de envío del correo que exige el sistema de listas grises no se realiza desde el mismo servidor que realiza el envío original con lo que nuestro sevidor toma el reintento como un correo diferente al original y no lo valida como correcto. La solución es fácil y seguramente estará “parcheada” en un futuro en nuestras Debian, pero por el momento tienes que solucionarla por ti mismo. Vamos a verlo.

En el directorio /etc/postgrey tenemos dos ficheros: whitelist_clients y whitelist_recipients. En ellos podemos incluir manualmente los servidores y direcciones de correo (respectivamente) que queremos validar automáticamente sin pasar por el sistema de listas grises. No obstante, hacerlo es una mala idea: en estos ficheros (sobre todo en el primero) es donde los mantenedores de Debian incluyen los servidores de correo que ya saben que dan problemas con el sistema de listas grises pero son servidores válidos. Posiblemente nuestro problema se resolverá en un futuro próximo cuando la gente de Debian incluya los servidores de Microsoft en este fichero pero mientras tanto tenemos que buscarnos una solución. Postgrey admite incluir en este mismo directorio dos nuevos ficheros con la misma funcionalidad pero donde podamos incluir nuestros propios servidores y direcciones de correo sin miedo a perder actualizaciones: whitelist_clients.local y whitelist_recipients.local.

Ahora ya sólo nos hace falta saber cuales son las direcciones de los servidores de correo de Microsoft. Afortunadamente están casi todas publicadas aquí. En algún foro he leído que es interesante añadir un par de líneas adicionales para validar los servidores de los servidores de Office 365. Al final, mi fichero whitelist_clients.local ha quedado así:

23.103.132.0/22
23.103.136.0/21
23.103.144.0/20
23.103.156.0/22
23.103.191.0/24
23.103.198.0/23
23.103.198.0/24
23.103.199.0/24
23.103.200.0/22
23.103.212.0/22
40.92.0.0/14
40.107.0.0/17
40.107.128.0/18
52.100.0.0/14
65.55.88.0/24
65.55.169.0/24
94.245.120.64/26
104.47.0.0/17
104.212.58.0/23
134.170.132.0/24
134.170.140.0/24
157.55.234.0/24
157.56.110.0/23
157.56.112.0/24
207.46.51.64/26
207.46.100.0/24
207.46.163.0/24
213.199.154.0/24
213.199.180.128/26
216.32.180.0/23
2a01:111:f400:7c00::/54
2a01:111:f403::/48
104.47.0.0/17
40.107.0.0/16
/.*outbound.protection.outlook.com$/
/outlook/

Ahora sólo queda reiniciar los daemons de postgrey y postfix para que los cambios tomen efecto y listo

Artículo Original: .

Este artículo pertenece a Un lugar en el mundo... Si quieres ver actualizaciones y comentarios interesantes visita el texto original en: Problemas de postgrey y las listas grises con los servidores de correo de outlook y hotmail de Microsoft || Hospedado en un Cloud VPS de Gigas.

Martes 28 de marzo de 2017

Rust en 5 minutos – #PicnicCode2017

El pasado 17 de marzo fue el Picnic Code en la Universidad de Valladolid. En el evento, organizado por el GUI y Cylicon Valley, tuve el honor de dar una Lightning Talk. Se trata de una charla de 5 minutos muy rápidos para exponer una idea. Mi Lightning Talk titulada Rust en 5 minutos iba dirigida a enseñar, sin entrar en muchos detalles, aquellas características que hacen de Rust un lenguaje seguro. No estaba nervioso hasta que subí al escenario… ¡y entonces ya empecé a estarlo! Hay algunos fallos frutos de los nervios y las diapositivas… bueno, podían haber funcionado mejor.

En cualquier caso, estáis invitados a ver Rust en 5 minutos.

La entrada Rust en 5 minutos – #PicnicCode2017 aparece primero en Blog - Adrianistan.eu.

Miércoles 22 de marzo de 2017

BlogDRAKE: La magia sigue viva

Lunes 20 de marzo de 2017

BlogDRAKE: 3 de mis imagenes estaran en Mageia 6

Lunes 13 de marzo de 2017

Guillermo Garron

Guillermo Garron
GNU Linux

{{ post.title }}

{{ post.content | xml_escape }}
Juanje Ojeda

Juanje Ojeda
Nada de particular

Cambio de profesión

El 8 de noviembre del año pasado cumplí 38 años y me siento mejor de lo que me sentía con 20, así que estoy muy contento :-)

Además, celebré mi cumpleaños regalándome un cambio de profesión. He vuelto a una de mis 2 grandes pasiones, el cuerpo humano y la educación física.

Después de estar un tiempo reciclándome (hace 15 años que estudié Ciencias de la Actividad Física y del Deporte y han cambiado muchas cosas desde entonces...) y dedicándome a mejorar mi salud, me decidí a tirarme a la piscina y dejar los ordenadores para dedicarme a las personas.

Hacía mucho que no estaba tan motivado con algo :-)

Ya llevo casi un año metido en esa aventura y cada día más motivado. Aprendo mucho cada día e intento compartir ese conocimiento en mi nuevo blog profesional:
Juanje Ojeda

La mayoría de mis clientes son personas con mi antiguo perfil. Personas sedentarias que trabajan todo el día con ordenadores y que les cuesta encontrar tiempo y fuerza de voluntad para tomar las riendas de su salud.
Incluso he empezado a ayudar de forma remota a antiguos compañeros de trabajo y gente del gremio. Es lo bueno de Internet y las nuevas tecnologías :-P
Entrenamiento online

Espero seguir así de contento e ilusionado con esta nueva etapa durante mucho tiempo. Pero si no es así, al menos lo intenté y lo disfrutaré mientras dure :-)
Juanje Ojeda

Juanje Ojeda
Nada de particular

Nace ASOLIF. Una apuesta de futuro y colaboración

Copio el anuncio que hizo el amigo Agustín sobre el nacimiento de la asociación de empresas de software libre federadadas (ASOLIF) en la lista de socios de Hispalinux, que el lo explica mejor de lo que lo haría yo ;-)

Ayer precisamente vi a Gonzalo (Fotón), que venía de la firma de la misma y que venía muy animado y esperanzado con el proyecto. Más tarde se nos unió Victor Fernandez (gerente, socio y amigo de Emergya) y tuvimos una cena muy agradable con tapitas y cervezas en la que hablamos de ASOLIF, los diferentes modelos de negocio y enfoques de las empresas que producen y consumen software libre, y más temas relacionados y muy interesantes.
Fué un debate intenso, interesante y muy constructivo. Que es lo más importante. Exponer opiniones, argumentarlas y sacar lo mejor de cada una de ellas para mejorar y avanzar.

Bueno, no me enrollo más, les dejo el mensaje de Agustín, para que aquellos que no están en la lista, puedan enterarse de esta interesante y prometedora noticia.

-----Original Message-----
From: Agustín Benito Bethencourt

Date: Fri, 29 Feb 2008 16:25:46
To:socios EN hispalinux PUNTO es
Subject: [Socios-HispaLinux] nace asolif


Hola a todos,

me congratulo en comentar que hoy nace oficialmente ASOLIF, la asociación de
empresas de software libre federadas. Forman parte de ella inicialmente las
asociaciones regionales ESLIC (Canarias), ESLE (País Vasco) y CatPL
(Cataluña). La inauguración ha sido auspiciada por el CENATIC esta mañana.

Como miembro fundador (y de la actual Junta Directiva) de ESLIC, quiero
decirles que se trata de una iniciativa que ha costado un año llevar adelante
y que esperamos todos sea la chispa que nos permita a las empresas de
software libre disponer de un foro efectivo, donde poder conectarnos formando
una red de empresas que den soporte e impulsen el software libre a nivel
empresarial en nuestro pais. El software libre SI tiene quien lo soporte en
España.

Sé que hay muchos empresarios que pertenecen a Hispalinux y sé que la propia
asociación ha servidor muchas veces como vehículo de nuestras demandas e
inquietudes. Sólo espero que la colaboración entre Hispalinux y la nueva
Federación sea lo más fructífera posible. Nos necesitamos.

Si eres profesional o empresa, permíteme invitarte a moverte para formar una
asociación de empresas en tu Comunidad (hay algunas que lo están haciendo ya)
y pasar a formar parte de esta Federación. Debemos estar todos para que el
esfuerzo que hemos puesto en esto tenga sentido.

Saludos
--
Agustín Benito Bethencourt
Grupo CPD
abenito @ grupocpd.com
http://www.grupocpd.com
http://agustin.ejerciciosresueltos.com
http://www.toscalix.blogspot.com
_______________________________________________


IMPORTANTE: Los mensajes y opiniones que aparecen en esta lista son de la exclusiva responsabilidad de sus autores. No son atribuibles a Hispalinux ni a los gestores de la lista.
-----Original Message-----


A ver qué tal va este asunto. ¡Mucha suerte a todos! :-)



Juanje Ojeda

Juanje Ojeda
Nada de particular

Sobre la BlackBerry desde la BlackBerry (III)

Lo prometido es deuda, aquí tienen el listado de mis aplicaciones favoritas para la BlackBerry.

He buscado cosas libres, pero es complicado encontrarlas. En su defecto he encontrado aplicaciones gratuitas. No es lo mismo, pero siendo prácticos, me sirven.

Listaré las aplicaciones por funcionalidad:


Y algunas aplicaciones vía web o wap:

¿Qué es lo que más uso yo? Pues después de probar mucho y pasarseme algo de la novedad lo que realmente uso y me resulta bastante práctico es:
(ordenado por frecuencia de uso)


Por cierto, el Opera Mini está muy bien, pero tiene algunas cosas que no terminan de gustarme y no se integra bien con la Perla. El trackball no funciona como esperas y no te deja ir a un enlace directamente con él, tienes que dar dos pasos...
Menú -> Selecionar

Usabilidad: -10 :-(

Una pena porque en cuanto a rapidez de carga y formateo de páginas es genial.

Otro día una escribo una revisión a algunas de estás webs o aplicaciones que uso. Pero espero que esta pequeña relación de enlaces le resulte útil a más de uno. A mí tener algo así me hubiera ahorrado bastante tiempo...
Otra cosa de la que me gustaría hablar es sobre el PIN. Si alguien tiene información útil e interesante sobre el tema, que lo diga, así me documento mejor del tema ;-)


Viernes 10 de marzo de 2017

BlogDRAKE: Humor: La comunidad en estos momentos 2
José María Morales Vázquez

José María Morales Vázquez
tecnología – Un lugar en el mundo…

Chuletillas (y XXXXVII) – Instalar un programa de debian Stretch mientras que usas debian stable (Jessie)

chuletaSi quieres instalar un determinado programa (y sus dependencias obligatorias) incluido en la próxima versión de Debian (Stretch) mientras continuas usando la versión stable (Jessie) puedes hacerlo de la siguiente forma:

En primer lugar edita tu fichero sources.list (en el directorio /etc/apt) e incluye al final las direcciones de los repositorios de Stretch pero sin eliminar ni modificar los que ya usas de Jessie. Por ejemplo así:

# Repositorios de Jessie
deb http://http.debian.net/debian/ jessie main contrib non-free
deb-src http://http.debian.net/debian/ jessie main contrib non-free
deb http://security.debian.org/ jessie/updates main contrib non-free
deb-src http://security.debian.org/ jessie/updates main contrib non-free

# Updates de Jessie, antes conocidos como 'volatile'
deb http://http.debian.net/debian/ jessie-updates main contrib non-free
deb-src http://http.debian.net/debian/ jessie-updates main contrib non-free

# Backports de Jessie
deb http://http.debian.net/debian jessie-backports main contrib non-free

#Repositorios de Stretch
deb http://http.debian.net/debian/ stretch main contrib non-free
deb-src http://http.debian.net/debian/ stretch main contrib non-free
deb http://security.debian.org/ stretch/updates main contrib non-free
deb-src http://security.debian.org/ stretch/updates main contrib non-free

# Updates de Stretch
deb http://http.debian.net/debian/ stretch-updates main contrib non-free
deb-src http://http.debian.net/debian/ stretch-updates main contrib non-free

A continuación creamos un fichero llamado stretch en el directorio /etc/apt/preferences.d y escribimos en el lo siguiente:

Package: *
Pin: release n=jessie
Pin-Priority: 900

Package: *
Pin: release n=stretch
Pin-Priority: 100

Con esto estamos modificando la prioridad con la que Debian actualizará nuestros paquetes. Por defecto instala siempre la versión más moderna de todas las que tenga disponibles en sus repositorios. Con este fichero le dará preferencia a cualquier paquete de jessie frente a uno de stretch aunque tenga una versión menor. Es decir, mantendremos nuestro sistema con las versiones de jessie salvo que un paquete no exista en esta y si en stretch… O se lo indiquemos manualmente durante la instalación que es lo que vamos a ver a continuación. Si quieres maś información sobre la forma de establecer preferencia para apt puedes echarle un vistazo a esta página.

Y ya lo tenemos todo listo. Ahora, tenemos que actualizar nuestros repositorios (apt update) y cuando queramos instalar un paquete directamente de stretch lo especificamos manualmente en el comando apt. Por ejemplo, si quisiéramos instalar la versión de apache de stretch lo haríamos así:

apt-get install -t stretch apache2

Artículo Original: .

Este artículo pertenece a Un lugar en el mundo... Si quieres ver actualizaciones y comentarios interesantes visita el texto original en: Chuletillas (y XXXXVII) – Instalar un programa de debian Stretch mientras que usas debian stable (Jessie) || Hospedado en un Cloud VPS de Gigas.

Jueves 02 de marzo de 2017

José María Morales Vázquez

José María Morales Vázquez
tecnología – Un lugar en el mundo…

Nueva página: Herramientas web de testing y monitorización

herramientas En muchos de los articulos que publico por aquí referencio herramientas web encaminadas a ayudar con la configuración, pruebas o análisis de diversos elementos de nuestra infraestructura informática. Servidores Web, certificados SSL, Disponibilidad, Correo Electrónico, Seguridad, etc. El enlace a la página está en el índice lateral y aquí:

Herramientas web de Testing y Monitorización

El propósito de esta nueva página es recogerlas en un único lugar para mantener una referencia completa, cómoda y perfectamente autorizada. Todas las herramientas relacionadas en ella son gratuitas al menos en un modo básico aunque podrían tener un modo de pago más completo. Y si conoces alguna otra que no aparece y crees que puede ser útil no dejes de enviármela a través de un comentario por favor. Gracias.

Artículo Original: .

Este artículo pertenece a Un lugar en el mundo... Si quieres ver actualizaciones y comentarios interesantes visita el texto original en: Nueva página: Herramientas web de testing y monitorización || Hospedado en un Cloud VPS de Gigas.

Domingo 19 de febrero de 2017

Marcelo Fortino

Marcelo Fortino
Fortinux

Tutorial Instalar PHP Server Monitor en Ubuntu GNU/Linux

En este tutorial vamos a instalar PHP Server Monitor en un servidor Ubuntu 14.04. PHP Server Monitor es una aplicación web open source que sirve para monitorear servidores web y/o sitios web.

Martes 07 de febrero de 2017

Ramón Miranda

Ramón Miranda
Ramon Miranda

TRUN videogame cover for VGsource


Talking about TRON is talking about a classic science fiction film and one of the best tributes to creativity and imagination in the world of cinema. Somewhat misunderstood film at first, but time makes justice and put TRON in its place. And if we talk about mythical elements of the film, we have to talk about bikelight racings ...

TRUN is a videogame created in Z80 assembler based on  original TRON.
The creators of the game are Vgsource, an indie development group that codes for MSX.
A few months ago, I was contacted to design their videogame cover and thus give it a greater visual impact.
It was an interesting work because from the first moment we looked for a 80's look"  immitating the style of covers of the era of Dinamic or Topo (spanish companies), where Azpiri was king illustrating those beautiful casettes and the less important was the result on screen (at least for people like me)
The first thing I did was to take references, and as it was not going to be otherwise the TRON movie itself was the main source of inspiration. I had several keys in mind while painting this illustration:
  •     blue
  •     Light
  •     No Fx overlay.
  •     Speed
  •     80's smell
Do you want to see how development was? Then we analyze the different phases briefly.

Sketches Phase

After analyzing what I want to emphasize in the image I start working on the sketches.
These are not very detailed drawings, but you can see the main elements of the design.


I decide for the first by movement feeling.



As we know the diagonals add movement to the composition and as I want to transmit speed I choose the design with that scheme and the broad to be able to study where to place each thing. Something that in the end I will change are the bikes. Finally will be even more "homage" to the original light bikes designed by Syd Mead.

References Phase

Being the game a "clone" of the game of TRON does not seem crazy to me to take references of the film. Since we are going to make a copy of a classic we will do well. Let it be noticed! That's why I create a composition with multiple references to then paint over what I need and get the result I want, not so photo but 2d. There is still a lot of work left. This system is not the only one I use for my illustrations.
This is the result of collage done inside Krita. All images have their corresponding copyright. We only use this as an idea. At the end, 100% of the illustration is repainted.



From this point we will work the Backgrounds. For the backgrounds, brushes that are quick for "covering big areas" are usually used. I use a brush that has the characteristic that diffuses the paint when low pressure is used and is adding more paint as the pressure increases. This is what I show you in the capture.




It has a Knive effect and belongs to the set I made for the DVD of the krita foundation #muses. If you are interested you can download it here totally free.

PACK bundle muses

Note: If for some reason you see that this brush produces somekind of "Lag", a very useful thing that speed up this brush and many of Krita's brushes is to use the "precision" parameter inside the brush editor and lower it from 5 to 1 If you also use large sizes you can increase the brush spacing to 0.5 or 0.7. It can be further optimized to gain speed in very large sizes.




Beyond it you will see that it is very fluid but loses a little of quality. These brushes require important computation operations for the CPU but give very interesting results.
What I want is to blur the photo effect but respecting the colors that are underneath while still being spots and at the same time giving me more freedom to paint over. You will see that the result is very pictorial. Handcrafted within the digital.

 
Now it's time to start defining all the elements of the image.
The face in the photo does not show an emotion according to what I look for, come on man! You're playing with your life in a race! :)
I have created this Gif for those who like to follow the evolution of the steps to follow.


You can see how the lighting changes as I work the metal. The gif was done with Gimp. It explains much more than a page of text. Among other things it is seen how the light is affecting the face of the character and his helmet.

The same thing happens in the background. When I go detailing the bikes and the kind of hangar where they come from.

When completing the image we run the risk of adding too many details. So beware of the Glow and the additive or color dodge modes that hook.
Making lines or curves accurately is complicated with freehand so one way to avoid headaches is to use paint assistants.

For example a use would be in the curve that defines the motorcycle panel of the character.


LightBykes

A main element of this image are the light bikes. Let's do something simple so we do not separate too much from what will be seen on the screen.


 

The problem as I see it is that the bikes need some lines of movement. This will convey more sense of career. In the end I choose lines not on the whole bike but in part. The result is something more shocking.


Logotype design for the cover

All we have left to do is create a logo for the cover design. For that task I better use an image editor like Gimp and a vector design program like Inkscape.

In Gimp I select the text tool with the previously downloaded typography that is very similar to TRON.


To vary slightly the layout i adjust and complete the contour of the word "TRUN" That way I have a good basis for editing in Inkscape and that can be adapted to any size without loss of quality.


Now we can add the text to our image.
And the end result is what we expected. Did you like it?

** If you liked the article and learned something to help you, you can support me by sharing the news with your friends. See you in the next article.

If you want to know more about the video game these links may seem interesting.


Some photos

Asociación de amigos del MSX




https://www.msx.org/es/news/software/es/trun-nuevo-juego-de-msx
 



Ramón Miranda

Ramón Miranda
Ramon Miranda

Portada para videojuego TRUN de VGsource


Hablar de TRON es hablar de un clásico de la ciencia ficción y de uno de los mejores tributos a la creatividad e imaginación en el mundo del cine. Película un tanto incomprendida al inicio, pero el tiempo le dio la razón y la puso en su lugar. Y si hablamos de elementos míticos de la película, tenemos que hablar de las carreras de motos de luz...

TRUN es un videojuego creado en ensamblador Z80 basado en TRON.
Los creadores del Juego son Vgsource, un grupo indie de desarrollo que programa para MSX.
Hace unos meses, me contactaron para diseñar su portada y así darle un impacto visual mayor.
Fue un trabajo interesante porque desde el primer momento se buscaba un "look" ochentero imitando el estilo de portadas de la época de Dinamic o Topo, donde Azpiri era el rey ilustrando esos bellos casettes y lo de menos era el resultado en pantalla ( al menos para personas como yo)
Lo primero que hice fue coger referencias, y como no iba a ser de otra forma la propia película de TRON fue la principal fuente de inspiración. Tenía varias claves en mente mientras pintaba esta ilustración:
  • Azul
  • Luz
  • No Fx overlay.
  • Velocidad
  • Espíritu 80's
¿Os apetece ver como fue el desarrollo? Pues analizamos las diferentes fases brevemente.

    Fase de Bocetos

    Después de analizar qué quiero destacar en la imagen empiezo a trabajar en los bocetos.
    Estos son dibujos no muy detallados en los que se pueden ver los elementos principales del diseño.



    Me decido por la primera por la sensación de movimiento.



    Como ya sabemos las diagonales añaden movimiento a la composición y como quiero transmitir velocidad elijo el diseño con ese esquema y lo amplio para poder estudiar dónde colocar cada cosa. Algo que al final voy a cambiar son las motos. Finalmente serán aun más “homenaje” a las originales motos de luz diseñadas por Syd Mead.

    Fase de referencias

    Siendo el juego un calco del juego de TRON no me parece una locura coger referencias de la película. Ya que vamos a hacer una copia de un clásico vamos a hacerlo bien. ¡Que se note! Por eso creo una composición con las múltiples referencias para luego pintar por encima lo que necesite y llegar al resultado que quiero, no tan foto sino más 2d. Queda aun mucho trabajo.Este sistema no es el único que uso para mis ilustraciones.

    Este es el resultado del collage realizado dentro de Krita. Todas las imágenes tienen sus derechos de autor correspondientes. Esto solo lo usamos como idea. Al final se repinta el 100% de la ilustración.



    A partir de este punto vamos a trabajar los fondos. Para los fondos normalmente se usan pinceles que sean rápidos que "cubran" Utilizo un pincel que tiene la característica que difumina la pintura cuando se ejerce poca presión y va añadiendo más pintura según aumenta la presión. Es este que os muestro en la captura.



    Tiene un efecto como de espátula y pertenece al set que hice para el DVD de la krita foundation #muses. Si os interesa os lo podéis descargar aquí totalmente gratis.

    PACK bundle muses

    Nota: Si por alguna razón veis que este pincel produce algo de "Lag", una cosa muy útil que acelera tanto este pincel como muchos de los de Krita es utilizar el parámetro "precisión" dentro del editor de pinceles y bajarlo de 5 a 1. Si además utilizas tamaños grandes puedes aumentar el espaciado del pincel hasta 0.5 o 0.7. Se puede optimizar aun más para ganar velocidad en tamaños muy grandes.




    Más allá verás que va muy fluido pero pierde un poco de calidad. Estos pinceles exigen operaciones de cómputo importantes para la CPU pero dan resultados muyyy interesantes.  

    Lo que quiero es desdibujar el efecto foto pero respetando los colores que hay debajo aun siendo manchas  y a la vez darme más libertad para pintar por encima. Veréis que el resultado es muy pictórico. Artesanal dentro de lo digital.


     

    Ahora es tiempo de empezar a definir todos los elementos de la imagen.

    La cara en la foto no muestra una emoción acorde a lo que busco, vamos hombre! ¡Que te estás jugando la vida en una carrera! :)

    He creado este Gif para los que les gusta seguir una evolución de los pasos a seguir.

    Se puede apreciar como va cambiando la iluminación según voy trabajando el metal. El gif lo hice con Gimp. Explica mucho más que una página de texto. Entre otras cosas se ve cómo la luz va afectandola cara del personaje y su casco.
    Lo mismo sucede en el fondo. Cuando voy detallando las motos y la especie de hangar de donde salen.


    Al ir completando la imagen corremos el riesgo de añadir demasiados detalles. Así que cuidado con el Glow y los modos aditivos o color dodge que enganchan.
    Hacer lineas o curvas con precisión es complicado a mano alzada por eso una forma de evitarnos quebraderos de cabeza es utilizar los asistentes de pintura.



    Por ejemplo un uso sería en la curva que define el panel de la moto del personaje.


    Motos de Luz.

    Un elemento principal de esta imagen son las motos de Luz. Vamos a hacer algo sencillo para no separarnos demasiado de lo que se verá en pantalla.

     

    El problema según veo es que las motos necesitan unas lineas de movimiento. Esto va a transmitir más sensación de carrera. Al final opto por lineas no en toda la moto sino en parte. El resultado es algo más impactante.


    Diseño de Logo para la portada

    Ya solo nos queda realizar un logotipo para el diseño de la portada. Para esa tarea mejor utilizo un editor de imágenes como Gimp y un programa de diseño vectorial como Inkscape.

    En Gimp selecciono la herramienta texto con la tipografía previamente descargada que es muy parecida a la de TRON.



    Para variar un poco el diseño ajusto y completo el contorno de la palabra TRUN De esa forma ya tengo una buena base para editarlo en Inkscape y que se pueda adaptar a cualquier tamaño sin perdida de calidad.

    Ahora ya podemos añadir el texto a nuestra imagen.
    Y el resultado final es lo que esperábamos . ¿Os ha gustado?
    **Si te ha gustado el artículo y has aprendido algo que te ayude, puedes apoyarme compartiendo la noticia con tus amigos. Nos vemos en el próximo artículo.
    Si quieres saber más del video juego estos enlaces te pueden parecer interesantes.

    Algunas fotos

    Asociación de amigos del MSX


    https://www.msx.org/es/news/software/es/trun-nuevo-juego-de-msx
     




    Domingo 29 de enero de 2017

    Gorka Urrutia

    Gorka Urrutia
    Nideaderedes

    Cómo instalar PrestaShop con Vagrant

    Para evtiar dolores de cabeza y tener que andar configurando un servidor local en Linux o algún Wamp en Windows o Mamp en Mac podemos usar Vagrant. He creado una máquina virtual que puedes usar como entorno de desarrollo para PrestaShop.

    Cómo instalar PrestaShop con Vagrant

     

    Gorka Urrutia

    Gorka Urrutia
    Nideaderedes

    La guía definitiva del código espagueti II: Que tus variables y funciones confundan al enemigo

    Porque elegir unos nombres horribles para tus variables y funciones es un arte:

    La guía definitiva del código espagueti II: Que tus variables y funciones confundan al enemigo

    Gorka Urrutia

    Gorka Urrutia
    Nideaderedes

    Programación orientada a objetos en PHP. 3: Encapsulación

    Otra entrega más (y ya van tres) del mini curso de programación orientada a objetos en PHP. Esta vez hablo de encapsulación. No te lo pierdas:

    Programación orientada a objetos en PHP capítulo 3: ¿Por qué no hacer todo public? (Encapsulación).

    Sábado 21 de enero de 2017

    Ramón Miranda

    Ramón Miranda
    Ramon Miranda

    Underwater Romance


    Hola a todos mis lectores y colegas. Se fue el 2016, y el 2017 ya lo tenemos aquí.
    Este pequeño artículo es de esos momentos en los que uno hace balance de cómo le fue el año y se pone nuevas metas.Para mi ha sido espectacular. Lo más importante es que al fin di el sí quiero con la mujer que amo. Se llama Lara y es parte fundamental de que esté aquí en Málaga, en esta tierra de luz y color donde tantas veces veranee de pequeño. Nos casamos de manera discreta y sin mucho ruido como queríamos que fuera. Así que en estos momentos estoy muy feliz. Quizás algún día asome por el blog, aunque de momento os digo que no tiene nada que ver con el mundo de la imagen.

    Ya metidos en materia también es muy destacable toda la evolución que ha habido dentro del mundo Krita. Increíble trabajo el de los desarrolladores. Una de las imágenes que la fundación decidió utilizar, fue esta que publico la cual pinté exclusivamente para ellos como recompensa para los que apoyaron la campaña de Kickstarter de Krita en este año. Este es el resultado de apoyar a Krita. la recompensa de ver cómo mejora cada día y ver que más usuarios puedan aprender desentrañando la imagen en alta resolución viendo todas las capas correctamente nombradas. Si quieres apoyar para que el proyecto sea aun mas grande aquí tienes un link https://krita.org/en/support-us/donations/




    Cabe destacar que la idea de hacer la ilustración como vista en el fondo del mar, se le ocurrió a mi mujer tras ver lo que estaba haciendo y los colores que estaba usando. 

    La cara de ella quizás ha sido la parte más difícil. 3 veces la repetí hasta dar con el gesto que buscaba, una pose de inocencia y a la vez de "me dejo seducir por este guapo sireno" ;D



    Si os gusta el resultado seguro que vais a disfrutar con el próximo artículo donde explicaré cómo se hizo esta imagen desde el boceto de color a la pintura acabada.

    Nos leemos






    English Readers

    Hello to all my readers and colleagues. 2016 has gone, and 2017 is already here

    This small article is one of those moments in which you think about how the year went and set new goals. For me it has been spectacular. The most important thing is that finally! I said "yes, i do" to the woman I love. Her name is Lara and she is a fundamental part for being here in Malaga, in this land of light and color where i spent so many summers as a child. We married discreetly and without too much noise as we wanted it to be. So right now I'm very happy. Maybe someday she will write something here, for now I swear you she has nothing to do with the world of the image. :D

    Talking about the picture... is also very remarkable all the evolution that has been in the Krita world. Incredible work for the developers. One of the images that the foundation decided to use, was this one that I published exclusively for them as a reward for those who supported Krita's Kickstarter campaign this year. The bakers with 50$ baked if i remember well received the image in high res and .kra format to learn more about how to use krita. If you want to support krita more there you have a link https://krita.org/en/support-us/donations/



    It is noteworthy that the idea of ​​making the illustration as seen on the bottom of the sea, occurred to my wife after seeing what i was doing and the colors i was putting on canvas.

    Mermaid's face has been the hardest part. I repeated 3 times until I found the gesture I was looking for, a pose of innocence and at the same time "I let myself be seduced by this handsome siren";D





    If you like the result you will enjoy with the next article where I will explain how this image was made from the color sketch to the finished painting.









    Domingo 08 de enero de 2017

    David Moreno

    David Moreno
    dm's blog

    Thanks Debian

    I sent this email to debian-private a few days ago, on the 10th anniversary of my Debian account creation:

    Date: Fri, 14 Aug 2015 19:37:20 +0200
    From: David Moreno 
    To: debian-private@lists.debian.org
    Subject: Retiring from Debian
    User-Agent: Mutt/1.5.23 (2014-03-12)
    
    [-- PGP output follows (current time: Sun 23 Aug 2015 06:18:36 PM CEST) --]
    gpg: Signature made Fri 14 Aug 2015 07:37:20 PM CEST using RSA key ID 4DADEC2F
    gpg: Good signature from "David Moreno "
    gpg:                 aka "David Moreno "
    gpg:                 aka "David Moreno (1984-08-08) "
    [-- End of PGP output --]
    
    [-- The following data is signed --]
    
    Hi,
    
    Ten years ago today (2005-08-14) my account was created:
    
    https://nm.debian.org/public/person/damog
    
    Today, I don't feel like Debian represents me and neither do I represent the
    project anymore.
    
    I had tried over the last couple of years to retake my involvement but lack of
    motivation and time always got on the way, so the right thing to do for me is
    to officially retire and gtfo.
    
    I certainly learned a bunch from dozens of Debian people over these many years,
    and I'm nothing but grateful with all of them; I will for sure carry the project
    close to my heart — as I carry it with the Debian swirl I still have tattooed
    on my back ;)
    
    http://damog.net/blog/2005/06/29/debian-tattoo/
    
    I have three packages left that have not been updated in forever and you can
    consider orphaned now: gcolor2, libperl6-say-perl and libxml-treepp-perl.
    
    With all best wishes,
    David Moreno.
    http://damog.net/
    
    
    [-- End of signed data --]
    

    I received a couple of questions about my decision here. I basically don’t feel like Debian represents my interests and neither do I represent the project – this doesn’t mean I don’t believe in free software, to the contrary. I think some of the best software advancements we’ve made as society are thanks to it. I don’t necessarily believe on how the project has evolved itself, whether that has been the right way, to regain relevancy and dominance, and if it’s remained primarily a way to feed dogmatism versus pragmatism. This is the perfect example of a tragic consequence. I was very happy to learn that the current Debian Conference being held in Germany got the highest attendance ever, hopefully that can be utilized in a significant and useful way.

    Regardless, my contributions to Debian were never noteworthy so it’s also not that big of a deal. I just need to close cycles myself and move forward, and the ten year anniversary looked like a significant mark for that.

    Poke me in case you wanna discuss some more. I’ll always be happy to. Specially over beer :)

    Peace.

    Miércoles 21 de diciembre de 2016

    Juanjo Amor

    Juanjo Amor
    DrAmor's Blog

    Acabemos con los intersticiales

    ¡Interstitials!

    Vaya palabro. “Interstitials”. Intersticiales en español. Anuncios intersticiales; que para la RAE serían aquellos que ocupan los intersticios, pero que, realmente, son anuncios que ocupan toda la pantalla y son especialmente molestos porque,

    • Impiden visualizar la página que queremos ver. Vamos, que molestan, y mucho más, que los pop-ups de toda la vida.
    • Incitan al click fraudulento: La mayor parte de las veces que pulsamos sobre el anuncio, no es para acceder al producto anunciado sino para cerrar el mismo. El botón para cancelarlo suele requerir de una especial destreza (o puntería) del usuario sobre su pantalla multitáctil… a menos que tengas los dedos del tamaño de la cabeza de un alfiler.

    Anuncio Intersticial, imagen de Google

    Pues bien, hace ahora más de 4 meses, Google anunció que iba a penalizar el uso de anuncios intersticiales en las búsquedas desde móvil a partir de enero de 2017, algo que ya está a la vuelta de la esquina.

    Es bueno recordarlo porque, a día de hoy, la mayor parte de las páginas de actualidad en Internet siguen incorporando este tipo de anuncios como si nada, haciendo muy incómoda la lectura, sobre todo en móviles, donde deshacerse del anuncio resulta complicado y por lo que, muchas veces, un servidor decide abandonar el medio de comunicación elegido para irme a uno alternativo que me informe más y me moleste menos.

    Aún me queda la esperanza de que esta penalización del buscador realmente consiga su efecto. Mientras tanto, seguiremos haciendo uso extensivo y abusivo de los bloqueadores de anuncios, pese a los avisos de determinados medios de que eso les hace daño.

    Lunes 05 de diciembre de 2016

    Emiliano A. González Salgado

    Emiliano A. González Salgado
    El blog de Emi

    Error al inicio de Linux debido a CUPS

    Uso Fedora 25 KDE. Desde hace tiempo y, con varias versiones anteriores. se está produciendo el mismo fallo al inicio del sistema.

    Para ver los errores que se han producido en el inicio de sesión, en los sistemas que incorporan Systemd, hay que teclear el comando:

    [root@HOST-PC ~]# journalctl -b -p err

    Uno de los que estaba arrojando últimamente era:
    cupsd[1213]: Missing value on line 11 of /var/cache/cups/job.cache.

    Los números 1213 y 11 pueden variar. El primero debe ser un índice de Journal (el registro de logs de Systemd) y el segundo hace referencia a la línea del fichero job.cache que produce el fallo.

    Es este caso era debido a que cups-pdf (la impresora virtual) al crear un fichero no le asignó un nombre en el archivo job.cache.

    Intenté borrar la caché de Cups desde el administrador de impresión (system-config-printer), pero no se encontraban trabajos pendientes ni terminados. También desde la interfaz web del servidor cups: http://localhost:631/jobs?which_jobs=all

    No era posible. No se podía borrar. Incluso eliminé el contenido de  job.cachecon un editor de texto, pero al volver a iniciarse el contenido estaba otra presente, así como el error se reproducía.

    Al final la solución llegó a través de la consola.

    Los comandos a ejecutar son:

    Parar Cups:

    [root@HOST-PC ~]# systemctl stop cups.service

    Ver la lista de trabajos completados:

    [root@HOST-PC ~]# lpstat -W completed -o

    Ver la lista de trabajos no completados:

    [root@HOST-PC ~]# lpstat -o

    Eliminar todos los trabajos:

    [root@HOST-PC ~]# cancel -a -x

    Esto cancelará todos los trabajos.

    Editar el fichero  /var/cache/cups/job.cache, borrar el contenido y guardar de nuevo.

    por ejemplo con nano como root

    [root@HOST-PC ~]# nano /var/cache/cups/job.cache

    Reiniciar el sistema y ver si se ha solucionado el fallo.

    SI las respuestas dadas aquí no funcionan:

    ps aux | grep printer kill {printer job}

    Este último comando no lo he probado. con lo anterior fue suficiente.

    Un saludo,

    Emiliano

     


    Jueves 01 de diciembre de 2016

    Luis Vilchez

    Luis Vilchez
    El blog de Jabba

    Pillars of Eternity, el heredero espiritual de Baldur's Gate para OSX y Linux

    Hablar de Baldur’s Gate es hablar del gran clásico entre los clásicos de los juegos de rol computerizado. Su legado y su influencia están muy presentes en gran cantidad de los títulos que conforman el panorama del videojuego actual. Un juego con una profundidad, libertad y capacidad de personalización nunca vistas hasta entonces. Un juego que muchos tenemos como uno de los mejores -sino el mejor- RPG de la historia.


    Quince años después Pillars of Eternity pretende devolvernos la magia, la ambientación, la jugabilidad y esa aura cautivadora y mítica propia de los grandes clásicos del género; un deleite para los sentidos de los veteranos en los juegos de rol y una experiencia inigualable para los recién llegados. Me han bastado unas semanas perdiéndome virtualmente por el mundo de Eora para confirmar que Pillars of Eternity es la oportunidad de volver a revivir un JUEGAZO infinity engine de corte clásico como los de antaño. Un juego que rezuma a Baldur's Gate del bueno por los cuatro costados. ¿Y sabéis lo mejor? Con versiones nativas para OSX y... ¡Linux!

    Es de recibo decir que gran parte de la culpa de todo esto la tienen los fans y el modelo kickstarter que sus creadores usaron para financiar el proyecto (por aquel entonces bajo el nombre de Project Eternity). El resultado ha sido un RPG de corte occidental distribuido por Paradox Interactive y desarrollado por Obsidian Entertainment, creadores de sagas como Fallout, IceWind Dale o Neverwinter Nights, además del citado Baldur’s Gate.

    Como en Baldur's Gate, la primera cosa que hay que hacer en Pillars of Eternity es crear un personaje. Aspectos como las diferentes ventajas e inconvenientes de cada raza, los atributos, las clases, las limitaciones de atributo por clase, las alineaciones morales, las habilidades complementarias, afinidad de armas, selección de conjuros, clases duales... habrá que tenerlos muy en cuenta antes incluso de comenzar la "aventura". Y seguramente no es el sistema de creación de personajes más amplio de la historia del género, pero sí es MUY completo. Incluso me atrevo a decir que podrá parecer algo complejo para los recién llegados pero hará las delicias de los veteranos del género. A fin de cuentas aprender forma parte de la esencia del rol y eso pasa por cosas como la creación de nuestro personaje. A continuación os dejo un vídeo para que lo veáis en acción.


    En otras plataformas no sé, pero en Linux sin duda estamos ante el juego del año :)

    Miércoles 30 de noviembre de 2016

    Raúl González Duque

    Raúl González Duque
    Linux – Mundo Geek

    Cómo crear un pendrive USB bootable con Ubuntu en Windows

    Tener un USB con Ubuntu siempre listo en el bolsillo puede ser muy útil para solucionar problemas con Windows, eliminar virus, realizar operaciones seguras en Internet, o simplemente para jugar un poco con Linux.

    Para crear una unidad USB arrancable con Ubuntu me gusta utilizar Rufus, que es gratuita, muy ligera, rápida y cuenta con versión portable. Además de Rufus, sólo necesitaremos una ISO de Ubuntu y un pincho USB con al menos 2GB de espacio, que debe estar vacío, o no importarte mucho su contenido, porque se formateará durante el proceso.

    Conecta el pincho USB a tu equipo y ejecuta Rufus.

    En “Dispositivo” selecciona tu pincho USB.

    Marca la opción “Crear disco de arranque con:”, selecciona “Imagen ISO”, y haz clic sobre el icono del CD Rom para abrir un diálogo en el que buscar la imagen ISO que has descargado

    USB booteable Ubuntu

    Pulsa el botón “Empezar”. Te avisará de que necesita descargar un par de archivos de Internet, pulsa en “Sí”.

    Cuando te pregunte por el modo de escritura de la imagen, selecciona “Escribir en modo Imagen ISO (Recomendado)”.

    A continuación te avisará de que va a proceder a formatear el dispositivo USB. Haz clic en “Aceptar” para empezar el proceso.

    Martes 08 de noviembre de 2016

    Raúl González Duque

    Raúl González Duque
    Linux – Mundo Geek

    ¿Cuántos usuarios de Linux se necesitan para cambiar una bombilla?

    Sea merecida o no, lo cierto es que los usuarios y desarrolladores de GNU/Linux tenemos fama de arrogantes, extremistas y de perdernos en los detalles. Desde el Proyecto GNU se toman con humor estos estereotipos calculando cuántos usuarios de Linux se necesitarían para cambiar una bombilla.

    • 1 para publicar un hilo en la lista de correo informando de que la bombilla se ha fundido
    • 1 para sugerir reiniciar la bombilla usando la línea de comandos
    • 1 para quejarse de que el usuario rompiera la bombilla
    • 1 para preguntar qué bombilla se debería instalar
    • 1 para aconsejar que no se use la palabra “fundida” para referirse a una bombilla rota, porque puede interpretarse que la bombilla se ha prendido fuego, en lugar de haberse estropeado por un exceso de corriente eléctrica
    • 25 para sugerir todos los tipos de bombilla imaginables
    • 5 para para decir que la bombilla fundida es un fallo de origen
    • 1 novato para sugerir instalar una bombilla de Microsoft
    • 250 usuarios para inundar el correo del susodicho novato
    • 300 para decir que la bombilla de Microsoft se pondría azul y tendrías que reiniciarla constantemente para que volviera a funcionar
    • 1 antiguo usuario de GNU/Linux, que todavía frecuenta el foro, para sugerir una iBombilla de Apple, que tiene un diseño fresco e innovador y sólo cuesta 250$
    • 20 para decir que las iBombillas no son libres, y que tienen muchas menos funcionalidades que una bombilla estándar 20 veces más barata
    • 15 para sugerir una bombilla nacional
    • 30 para decir que las bombillas nacionales son copias de las bombillas extranjeras y que no ofrecen nada nuevo
    • 23 para discutir si la bombilla debe ser blanca o transparente
    • 1 para recordar a todo el mundo que el nombre correcto es GNU/Bombilla
    • 1 para decir que las bombillas son sólo para usuarios de Window$ y los usuarios de GNU/Linux de verdad no tienen miedo a la oscuridad
    • 1 para anunciar finalmente el modelo de la bombilla elegida
    • 217 para descartar el modelo escogido y sugerir otro
    • 6 para quejarse de que el modelo elegido tiene elementos propietarios, y que debería usarse otro
    • 20 para decir que una bombilla 100% libre sería incompatible con el interruptor
    • Los mismos 6 anteriores para sugerir cambiar el interruptor por uno compatible
    • 1 para chillar “¡DEJAD DE DISCUTIR Y CAMBIAR LA P*#@!%¡# BOMBILLA DE UNA VEZ, POR EL AMOR DE DIOS!”
    • 350 para preguntar al usuario anterior a qué Dios se refiere, y si tiene pruebas empíricas de su existencia
    • 1 para explicar cómo funciona la electricidad y por qué una bombilla eléctrica es ineficiente
    • 1 para decir que no se puede confiar en una bombilla fabricada por una corporación y que deberíamos confiar en bombillas hechas por la comunidad
    • 1 para publicar un enlace a un archivo ODF explicando cómo construir una bombilla desde cero
    • 14 para quejarse del formato del archivo anterior, pidiendo que se envíe en txt o LaTeX
    • 5 para decir que no les gustó la decisión y van a hacer forks de la instalación eléctrica de la casa para instalar una lámpara mejor
    • 1 para publicar una serie de comandos a introducir para cambiar la bombilla
    • 1 para comentar que ejecutó los comandos y obtuvo un mensaje de error
    • 1 para aconsejar que los comandos deberían ejecutarse como root

    Y finalmente:

    • El padre del usuario original, que mientras todos estaban discutiendo, se acercó a la tienda y compró la bombilla más barata que vendían

    Lunes 07 de noviembre de 2016

    Raúl González Duque

    Raúl González Duque
    Linux – Mundo Geek

    Los 10 comandos más útiles de Linux

    CommandlineFu es una web donde los usuarios pueden enviar sus comandos Linux favoritos, añadir comentarios, y votar los comandos enviados por otros usuarios; un recurso imprescindible si queréis convertiros en verdaderos expertos en el uso de la consola. Y para muestra, un botón: estos son los 10 comandos más votados por sus usuarios.

    sudo !!

    Ejecuta el último comando introducido como root.

    python -m SimpleHTTPServer

    Inicia un servidor web que sirve los archivos del directorio actual en http://localhost:8000

    ^foo^bar

    Ejecuta el último comando, reemplazando el texto “foo” por “bar”

    Ctrl + X, Ctrl E

    Invoca un editor de textos en el que poder escribir el comando que vamos a ejecutar. El comando se ejecutará una vez se cierre el editor

    Alt + .

    Inserta el último argumento utilizado en el punto en que esté situado el cursor

    reset

    Resetea la consola

    mount | column -t

    Muestra los puntos de montaje actuales con un formato amigable para la lectura

    echo “ls -l” | at midnight

    Ejecuta un comando en el momento indicado

    curl ip.appspot.com

    Descarga el documento de http://ip.appspot.com para mostrar la IP externa del equipo

    man ascii

    Muestra la página de ayuda con la tabla de caracteres ASCII

    Domingo 30 de octubre de 2016

    Marcelo Fortino

    Marcelo Fortino
    Fortinux

    Tutorial usar git-annex para sincronizar archivos entre dispositivos GNU/Linux

    Tutorial usar git-annex como repositorio de archivos Una forma de tener nuestros archivos sincronizados entre el notebook, desktop y otros dispositivos es usar como herramienta git-annex. Git-annex gestiona archivos con Git sin verificar el contenido de los mismos. Esto permite trabajar con archivos grandes usando repositorios sincronizados.

    Martes 18 de octubre de 2016

    わき毛の抜毛には女性の大きな関心事だ。幾ら素敵な装い

    わき毛の抜毛にはマミーの大きな関心事だ。
    幾ら素敵な装いをし立としても、傍らのむだ毛が伸びていたら、ガッカリですね。
    好感触に感じていた輩も瞬く間にきらいになってしまうかも知れません。
    薄着の季節では余計に傍ら後が開いた洋服が多くなりますし、自分で処理をすると皮膚が炎症を起こしたりして余計な不便まで秘める片付けになります。
    抜毛店舗実践のお値段ですが、いつの抜毛店舗かで予算は違ってきますし、希望の抜毛要素次第で移り変わるでしょう。
    大手の抜毛店舗でよく言えるようなお得なキャンペーンの利用によって、案外低料金の抜毛が可能になる場合もあるでしょう。
    またワキや拳固など抜毛ニーズ部位ごとに通うお店を取りかえる、つまり抜毛要素それぞれでちがう抜毛店舗に通うようにするといった華奢に抜毛が進められそうです。
    また一つのお店だけを利用するのに比べてリザーブを格段に取り去り易く罹るのもうれしい部分だ。
    経済的に無理なく抜毛しようと、最初から抜毛器で自己処理やる分と抜毛店舗に任せるパイと、区別してある輩もある。
    適性もありますが、自家用の抜毛器を上手に使えば、各回、抜毛のために抜毛店舗を予約しなくてもすむでしょう。
    厳しい部分は抜毛店舗で施術してもらい、そのほかの部分は抜毛器で自己処理やる為す。
    但し抜毛器もそれなりの性能のものでないとその抜毛器による店だけムダ毛余りしてしまう結果、購入前のプレ認証は不可欠です。
    カラダ抜毛をしたら、ムダ毛のお手伝いを自分でするわずらわしさから解放され、処置がヤバイ楽になる事は確実です。
    但し、お金が幾らくらい陥るのか、ムダ毛はどのくらいきれいになるのか事前に調べておきましょう。
    カラダ脱毛するお店や店舗にて、抜毛作用やそのために加わる費用が非常に違ってきます。
    むだ毛の抜毛の手当て方法の中で、ニードル法は無限抜毛作用が最も期待できる抜毛法だと思われます。
    今は病院です抜毛病舎や一部の抜毛店舗でしか行われていない抜毛法だ。
    著しい痛みがあるので、興味はレーザー抜毛の方が高いようですが、大きい効果が期待できる結果、この方法をわざと選ぶ人も少なくないようです。
    間違って認識してる輩もいるようですが、店舗をめぐってもツルッパゲスキンになるまで、一度や二都度の手入れで抜毛が完了し立とは言えません。
    抜毛を受ける要素にても変りますが、おおまかに言って、6回から18回ほど抜毛を受ける人が多いようです。
    ですが、スキンへの恐怖によって、手入れを受けた数日後にまた抜毛が行なえる所以ではなく、頭髪回転の階級が二ヵ月なので、それくらいのスパンを空けて伺うのが最適です。
    ただただ「抜毛」と言ってもこのように長期戦になる結果、売店が多いなどで利用しやすい店舗で行ないましょう。
    できるだけ抜毛代金を安く終えるために、破格値の抜毛店舗を探している輩は少なくないです。
    ただし激安予算ばかりが売りの抜毛店舗は無事故や浄化をおろそかにしているかも知れません。
    低価格なパイ、普通の回数ではほとんど効果が出ないとか、スキンを傷める結果になっては給与も損害ですが、かけた日数ってスキンは戻って来ないでしょう。
    スキンを傷めたらムダ毛手当ては当分できません。
    予算の低廉さばかりを代物にする抜毛店舗の場合はあらかじめ評価や手答えをチェックしておいた方がいいでしょう。
    きれいに脱毛するには少々抜毛店舗に通うことになりますから、自分に当てはまるリザーブ切り口があるか確認してから契約するべきです。
    立とえばリザーブ切り口が連絡のみの抜毛店舗だと忙しさにかまけているとリザーブ電話をかけるのが後回しになりがちだ。
    リザーブがタブレットから叶う抜毛店舗だったら、単なる合間に予約できるので、心づもりをずらす必要がありません。
    綺麗に抜毛しようと思ったら、抜毛店舗に何度となく乗り物を運ばなければなりませんから、手入れのリザーブが取り易いかどうかは店舗選びの重大要素のひとつです。

    Lunes 17 de octubre de 2016

    家屋でのムダ毛加工はヘビーな操作だ。剃ろうにもビデオラ

    住宅でのムダ毛作製はヘビーな工程だ。
    剃ろうにも映像路線や背中は上手くできなかったり、毎日ムダ毛のお手入れをするのは煩わしくて疲れたり、問題に感じている方もいるのではないでしょうか。
    抜け毛店舗を利用すれば、たえず苦労しているフィールドの抜け毛も平安、自宅での作製のもめごとも気にしなくてよくなります。
    体内抜け毛店舗はたくさんありますが、抜け毛で失敗し立と感じないためには、じっさいに体内抜け毛を先輩のクチコミを聞いてみるのが一番良いでしょう。
    感想は自身によるの部分はありますが、誰もがいいという店舗は粗方決まってくる。
    重要視するのは出来ばえや早さですとか、やはり短いのが有難いとか、自分が抜け毛でやはり重視する主題を決めておくってきっと納得できるはずです。
    妊婦様であれば、多くの抜け毛店舗ではメンテナンスを行ないません。
    懐妊内輪はホルモンの不調でメンテナンスを通じても抜け毛の効力が出にくかったり、神経質になっているスキンは、少しのモチベーションも荒れてしまうからだ。
    抜け毛が完了していないうちに懐妊のリサーチが出てきたら、店舗によっては産後2ヶ月ぐらいまで休会ができる店舗もあるので申込む前にそぐういう通り道や制度を確認しましょう。
    抜け毛料金がサラリー制のところもありますから、一通りの抜け毛承認までに総額が予見できずに困ってしまっ立という自身も要るかも知れません。
    体内抜け毛総額確認の際には、抜け毛フィールドといった抜け毛承認までに陥る値段を比べて、メンテナンスのアポイントメントを入れ易い店舗を選ぶことも重要なのです。
    どんどん一度の抜け毛で全てのパートを施術して得る店舗ならひときわ容易でしょう。
    指のムダ毛は凄く自身には映るものです。
    他人のしかたを見ればわかりますが、例えネイルやかざりで盛装していても、指頭髪があるという冴えない自身認定されてしまう。
    指のお手入れの基本としてムダ毛作製を抜け毛店舗で講じる側は以前からすごく多いのです。
    しかたや指のように表皮の無い部分は考えも素晴らしいので、抜け毛手法は事前にぐっすり検討したほうがよいでしょう。
    見立て抜け毛は効力が持続するかわりに痛みを伴うので、低モチベーションの光線抜け毛様式を施術するのが一般的なようです。
    出向ける場所に一種しか仕事場がない場合はレンジがありませんが、仕事場が沢山あれば、各仕事場の詳細などを比較してから、抜け毛店舗を選択するという良いでしょう。
    では、効力、総額、アポイントメントの取り方、姿勢行為などをサイトなどの人づてなどを見て確認しなければならないことが山ほどあります。
    いくつか選択をサイトなどで通り道や人づてにおいて選んでから必ず、自分自身に合っているのか、事実通り道にあたって判断しましょう。
    ニードル抜け毛は何かと障害が多いと言います。
    最近のレギュラーな抜け毛法ではないのでほとんど知られていない手法なのかもしれませんが、ニードル抜け毛にはひどくの痛みがあるのです。
    もう一度、毛孔の全てに針をより刺していくのです極の時間がかかります。
    痛みがある上に長時間のメンテナンスが必須となるって、それなりに障害も多くなってくるのだと思います。
    華奢ゾーンの抜け毛を抜け毛店舗ですると、キレイな出来ばえだったし、肌荒れが起きにくいといわれています。
    ただし、抜け毛店舗の全てがVIO抜け毛が出来ない場合もあるのでウェブサイトなどで確認してから行きましょう。
    華奢ゾーンの抜け毛は気まずいという方も、よくいますが、同性それぞれですし、ベテランが行なうほうが自分で行うからセキュリティだ。

    Domingo 16 de octubre de 2016

    Marcelo Fortino

    Marcelo Fortino
    Fortinux

    Tutorial instalar Plone CMS en Ubuntu server

    En este tutorial veremos como podemos instalar el gestor de contenidos Plone en un servidor Ubuntu 14.04 o 16.04. Plone es un gestor de contenidos basado en el servidor de aplicaciones Zope que es bastante utilizado como Intranet en gobiernos y empresas, entre ellos, el gobierno brasileño, la universidad de Oxford (Reino Unido) o Google.

    仮に代価に余裕があるなら、その代価で抜毛ショップの加療

    もしも財貨に余裕があるなら、その財貨で抜け毛店先の施術費用を払って仕舞うのもありです。
    資金で支払うのですから、あとでカードの支払いお日様も気になりません。
    ただし、仮に資金が手もとにあって高額な先払いをしてしまうと、途中で通えない原因ができ立ときは空白分の精算が必要になります。
    それに、抜け毛店先そのものが潰れたら、先払いしてあった分だけ損をすることになります。
    少額だったり、そのつど払う場合は資金支払いも良いですが、そこそこの金額に繋がるようならカード支払いをお薦めします。
    月々定額(月収制)の抜け毛店先の場合、清算が明確なので気軽に抜け毛できるのでお薦めです。
    とはいえ体の一端しか抜け毛したくないときは、月収制を選ぶというかえってロスかも知れません。
    発毛周期を見ながら脱毛するので、もし1ポイントだけなら隔月に一度の抜け毛になるからだ。
    そのかわり、思いポイントが多いほど月収制による有難みがあるといえるだと言えます。
    ご自身の場合はどうしたいかを明確にして、ピッタリ合う抜け毛店先によるっていいだと言えます。
    「ムダ毛の憂慮」で多くの人が走り込む抜け毛スパのランキングには、大御所エステティックサロンのTBC、エルセーヌなどのエースがデイリー、上位に食い込んでいらっしゃる。
    これとは別に、抜け毛店先をこういうランキングに含めたタイミング、たとえば、ミュゼプラチナム、シースリー(C3)、抜け毛研究所、等々が上の順番に名称を連ねます。
    人気といえば、ピュウベッロやキレイモなどもあります。
    その中には、要望する抜け毛フィールドを通じてもくろみごとに分けて向かう方もいらっしゃる。
    何とか抜け毛スパに通うとすると、気にならなくなるまで脱毛するなら12回等前文向かう必要があるようです。
    気になるフィールドが上腕や脚等、他とくらべて分厚く無いポイントであるならば、5、6回の施術で感動する方もあるだと言えます。
    ただし、横やアンダーヘア等の眼たつ濃い毛が生えてしまってあるところは、ベイビー(ベイビーが生まれるまでは乳幼児好きじゃなかった方も、自分の乳幼児が産まれてみると、ベイビーがかわいくて仕方がないということがよくあるみたいです)のお肌の様なツルッとしたお肌にしようとすると、上腕や脚等の二ダブルは施術回数が必要になるケースと思います。
    皮膚がデリケートであるヤツですと剃刀負債が発生することがあるだと言えます。
    そういう人におすすめしたいのが抜け毛店先における灯抜け毛だ。
    これならば、アトピー風習の人も安全に施術をうけることが出来る為す。
    横の抜け毛に耐えるのだったら、ぜひ試してちょうだい。
    駅前駅近で目にする行いの多い抜け毛店先ですが、ムダ毛と呼ばれる体の邪魔な毛に、美専用の電気道具などを使用し、ムダ毛が出現するチェーンを遅らせたり、発毛しないように治療をするおみせのことです。
    以前は抜け毛製作というとエステでするというのが一般的なスタンスでしたが、抜け毛にもハイテクノロジーが普及した現在では短時間で効率的に抜け毛できるようになった事で抜け毛というサービスに限定して商売始めるサロンの飛躍的な繁殖につながったりゆうだ。
    ほとんどの女性がムダ毛製作を考え始めるのは温暖な春から初夏程だ。
    皮膚が周囲にふれる機会が多くなりますし、歩き、上腕のムダ毛だけでなく横などもプロフェショナルにきれいにしてもらいたいといった指し初めるのです。
    とくにいよいよ顧客はこの時期が多く、抜け毛店先が大混雑始めるぐらいですし、貸し賃は安くありません。
    貸し賃が短いのは、温度が薄くなり皮膚の登場がなくなる年代だと言えます。
    抜け毛だけでなく益々まとまりたいヤツはジェイエステティックが良いだと言えます。
    美顔、シェイプアップスパ、美貌脚も揃えたすべて美店先だ。
    一般の抜け毛店先みたい、灯方式の抜け毛を取り扱っています。
    格安で同店の美肌抜け毛を体験できるお試し教科も用意され、サロン単位の設定もスムーズなのがジェイエステティックのウリだ。
    サロンは全国に100サロン以上あり、思わぬところにおみせがあったり決める。
    もしも近くに支店があったら、キャリア教科などで様式を探るのもいいかも知れませんね。

    Lunes 29 de agosto de 2016

    David Moreno

    David Moreno
    dm's blog

    Webhook Setup with Facebook::Messenger::Bot

    The documentation for the Facebook Messenger API points out how to setup your initial bot webhook. I just committed a quick patch that would make it very easy to setup a quick script to get it done using the unreleased and still in progress Perl’s Facebook::Messenger::Bot:

    use Facebook::Messenger::Bot;
    
    use constant VERIFY_TOKEN => 'imsosecret';
    
    my $bot = Facebook::Messenger::Bot->new(); # no config specified!
    $bot->expect_verify_token( VERIFY_TOKEN );
    $bot->spin();
    

    This should get you sorted. What endpoint would that be, though? Well that depends on how you’re giving Facebook access to your Plack’s .psgi application.