Vivir sin Windows

Hoy hace dos años dejé de fumar. Sin tratamientos ni nada. Simplemente decidí dejar de fumar y lo dejé. Parece fácil pero no lo es. Esa decisión requiere cambiar nuestra forma de ver el mundo. Cambiar nuestra forma de hacer las cosas en nuestra vida cotidiana y sobre todo cambiar la manera de enfrentar las dificultades. Antes de esa decisión uno sabe que fumar hace mal, no necesita imágenes horribles en un paquete de cigarrillos para saberlo. Se siente todo el tiempo. Uno sabe que fumar hace mal pero no podemos imaginarnos vivir sin fumar, estamos convencidos de que el cigarrillo es una parte inseparable de nuestra vida y por lo tanto no podríamos vivir sin fumar. En realidad es cierto, el cigarrillo forma parte de esa vida que llevamos. Para dejar de fumar hay que cambiar nuestra forma de vivir y aprender a vivir sin recurrir al cigarrillo. Esa es la parte difícil, decidirse a cambiar nuestra forma de vivir. Aún después de haber cambiado nuestra forma de vivir nuestra adicción encuentra siempre una manera de invitarnos a volver a nuestra vida anterior. Liberarse de vicio es decidirse a recordar constantemente que uno no quiere volver a las cosas buenas de su vida anterior porque las malas son mucho peores.

Cuando tenía 15 años un amigo, y mentor en muchos aspectos de mi vida pero principalmente en informática, me prestó un CD con Mandrake 8.0 y me dijo que vea si lo podía instalar. Para ser sinceros la instalación era más sencilla y amistosa que la de Windows. No importaba, había instalado GNU/Linux y me sentía un hacker. Mi amigo viendo que me había agrandado mucho me pasó otro CD. Esta vez era Slackware. El CD no era booteable, venía con un manual en texto plano y en inglés que explicaba la instalación empezando por instalar LiLo en un diskette para bootear desde el CD. Tardé 4 horas leyendo la documentación que traía el CD (no había Internet en ninguna casa esa época) y decidirme a empezar y 4 horas en instalarlo. Y aún así no quedó bien. Tuve que escribir un script para montar y otro para desmontar los CD porque no se hacía automáticamente. La lección estaba aprendida, instalar GNU/Linux no te hace saber mucho. Por aquel entonces jugaba mucho y fue la excusa perfecta para volver a Windows porque no iba a poder jugar en GNU/Linux.

Hace 12 años, por Julio o Agosto decidí instalar GNU/Linux junto con Windows porque estaba cansado de tener que luchar contra Windows para que ande bien. Estaba cansado de Windows pero creía que, como cuando conocí a GNU/Linux 7 años antes, no iba a poder vivir sin Windows. Instalé Ubuntu, que por ese entonces ya estaba encaminada a ser la más conocida. La usé 6 meses seguidos y luego volví a bootear en Windows para comparar. Tardó 5 minutos en bootear, los juegos crasheaban, mensajes de error cada minuto. Salí lo más rápido que me dejó y borré la partición. En ese momento decidí que iba a usar solo GNU/Linux. No fue fácil. Tuve que cambiar muchas cosas en mi forma de usar la PC. Y tuve que resignarme a no jugar juegos nuevos. Pero los beneficios de usar Windows no se comparan con las cosas malas que tiene.

No es fácil. Casi todo el mundo te dice que usar Windows vale la pena. Y cada tanto uno lo piensa pero yo ya me liberé de ese vicio informático. Constantemente recuerdo que no quiero volver a esa vida.

Anuncios

Éxodo Githubjeño

Ayer nos enteramos que el triste rumor de que uno de los enemigos de la libertad quería comprar Github era cierto. El bastión mas importante de desarrollo de Software Libre ahora está en manos de uno del mas importante enemigo

Captura de pantalla de 2018-06-05 19-29-56

de la libertad de los usuarios. Con algunos pocos programas y frameworks con licencias complicadas que permiten mirar el código fuente y cambiarlo pero el binario que distribuyen es completamente privativo, como es el caso de Visual Studio Code, no nos van a convencer de que aman al software libre y sus libertades.

Algunos argumentarán que Github es privativo y que no corre software libre. La Free Software Foundation no tiene todavía consenso sobre si un servicio que corre sobre software privativo se puede llamar privativo. El propio Richard Stallman aconseja no llamar privativo o libre a un servicio. Lo cierto es que Github era la casa de millones de proyectos de software libre y la comunidad mas grande de desarrolladores de software libre.

El enemigo se adueñó de la casa de nuestros proyectos por lo tanto propongo a todos los usuarios de Github que imitemos a los patriotas de antaño, hagamos el Éxodo Githubjeño eliminando nuestros proyectos y usuarios para que el enemigo no tenga nada de lo cual pueda sacar provecho.

GtkTemplate Para la Victoria o Cómo parir GtkTemplates

GtkTemplates te permite unir de manera sencilla y transparente para el desarrollador los widgets definidos en un xml y una clase nuestra que los utilice sin necesidad de utilizar GtkBuilder directamente. De esa manera tenemos separadas las capas de interfaz y de lógica de una misma clase. Sin dudas, es un placer sin parangón el ver el código resultante, tan sencillo, tan limpio.

Durante los últimos dos meses estuve tratando de aprender a usar en forma efectiva los queridos, y nunca bien ponderados, GtkTemplate. Me costó mucho esfuerzo aprender a usarlos, pero lo logré.

¿De qué estás hablando Willis?

Nosotros, en Nomeolvides, como estábamos aprendiendo, elegimos no usar archivos .xml con la definición de los widgets propios de determinada clase. Simplemente los agregábamos y definíamos en el código. No entendíamos aún cómo trabajar bien con los archivos xml y GtkBuilder. GtkTemplates te permite unir de manera sencilla y transparente para el desarrollador los widgets definidos en un xml y una clase nuestra que los utilice sin necesidad de utilizar GtkBuilder directamente. De esa manera tenemos separadas las capas de interfaz y de lógica de una misma clase. Sin dudas, es un placer sin parangón el ver el código resultante, tan sencillo, tan limpio.

¡Cállate y toma mi dinero!

Cuando vi la publicación de Tristan Van Berkom me enamoré de GtkTempaltes en vala. Intenté aprender por aquel entonces, pero no tuve buenos resultados. Hace unos meses estamos amagando que empezamos una nueva aplicación con mi hermano y un amigo, así que quería hacerla desde el principio con GtkTemplate. Actualmente estoy portando Nomeolvides para que use al máximo GtkTemplates y la verdad es que es un trabajo pesado. Así que mejor hacerlo desde el principio.

Primero tengo que tomar mis piernas y sacarlas… y ahora saco las brazos con la cara

Lo primero que necesitamos para usar templates es compilar los archivos xml en un binario. Eso es sencillo con GResources, usando un simple xml que le diga a GResources qué archivos compilar y cuál es el path por el que vamos a acceder a ellos una vez compilados. Para automatizar la compilación vamos a necesitar agregar algunas líneas al Makefile.am y al configure.ac, si usamos autotools, claro.

mi-proyecto.gresources.xml

<?xml version="1.0" encoding="UTF-8"?>
<gresources>
  <gresource prefix="/mi-organizacion/mi-proyecto/">
    <file>mi-widget.ui</file>
  </gresource>
</gresources>

configure.ac

GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable glib_compile_resources gio-2.0` AC_SUBST(GLIB_COMPILE_RESOURCES)

Makefile.am

mi_proyecto-resources.c: mi_proyecto.gresources.xml
	$(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) \
	$(srcdir)/mi_proyecto.gresources.xml \
	--target=$@ --sourcedir=$(srcdir) --c-name mi_proyecto --generate-source

mi_proyecto_SOURCES = \
	gtk_foobar.vala config.vapi mi-widget.vala mi_proyecto-resources.c

mi_proyecto_VALAFLAGS =  \
	--pkg gtk+-3.0 \
	--target-glib=2.38 \
 	--gresources mi_proyecto.gresources.xml

Muy bien, ahora necesitamos crear el archivo xml con la definición de los widgets que va a tener nuestra clase. En este punto hay que aclarar algo: los templates son clases propias que heredan de un widget. No se puede hacer templates de objetos que no hereden de GtkWidget.

mi-proyecto-mi-widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="3.16"/> 
  <template class="MiProyectoMiWidget" parent="GtkGrid">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="halign">center</property>
    <property name="valign">center</property>
    <property name="row_spacing">20</property>
    <property name="column_spacing">50</property>
    <child>
      <object class="GtkLabel" id="label-mi-widget">        <property name="visible">True</property>        <property name="can_focus">False</property>        <property name="label" translatable="yes">Mi label</property>      </object>
      <packing>
        <property name="left_attach">0</property>
        <property name="top_attach">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkEntry" id="entry-mi-widget">        <property name="visible">True</property>        <property name="can_focus">True</property>      </object>
      <packing>
        <property name="left_attach">1</property>
        <property name="top_attach">0</property>
      </packing>
    </child>
  </template>
</interface>

Y por último necesitamos un archivo vala que implemente nuestra clase.

mi-widget.vala

[GtkTemplate ( ui = "/mi-organizacion/mi-projecto/mi-widget.ui" )]
Public class MiProyecto.MiWidget : Gtk.Grid {}

De esta manera cuando instanciemos MiWidget (y lo agreguemos a algún container) se va a ver tal como lo definimos en el archivo xml.

Esta clase no tiene aún funcionalidades lógicas, por eso está vacía. Si quisiéramos hacer que esta clase funcione igual, pero sin que sea un template, tendríamos que definir los widgets y sus propiedades en el código. por ejemplo:

mi-widget.vala

using Gtk;

public class MiProyecto.MiWidget : Gtk.Grid {
  public MiWidget () {
    this.set_halign ( Align.CENTER );
    this.set_valign ( Align.CENTER );
    this.set_row_spacing ( 20 );
    this.set_column_spacing ( 50 );

    var label-mi-widget = new Label.with_mnemonic ( "Mi Label" );
    var entry-mi-widget = new Entry ();

    this.attach ( label-mi-widget, 0, 0, 1, 1 );
    this.attach ( entry-mi-widget, 1, 0, 1, 1 );
  }
}

Si bien la clase sigue siendo pequeña, las líneas que hay no contienen lógica sino las definiciones de la interfaz gráfica.

Esto es una muestra. En las próximas publicaciones voy a hablar más cosas de algunos aspectos, como signals o acceder a widgets que están definidos en el xml, y problemas comunes con los que tuve dificultades.

Un abrazo!

Actualizar glibc a 2.16.0-2 en Arch Linux o /lib pasa a ser un symlink de /usr/lib en Arch Linux

Desde hace tiempo que vengo leyendo en la mailing list de Arch, ciertos conflictos que se daban al actualizar glibc a la versión 2.16.0. El conflicto principal es debido a que /lib deja de ser un directorio para ser un enlace dinámico (symlink) de /usr/lib.

Como mi pc principal es usada por varias personas, no es recomendable dejar el sistema inutilizado por jugar con la configuración, porque no siempre tengo tiempo para arreglarlo rápidamente. Por esa razón tengo una instalación de Arch que no usa nadie con la que puedo romper todo sin culpa probar cosas para aprender antes de hacerlas en la instalación principal. Al intentar actualizar glibc en mi Arch de pruebas rompí todo el sistema(claro que no usé force :P), en algún momento lo arreglaré. Hoy glibc 2.16.0-2 pasó a [Core], decidí actualizarlo y anotar los pasos previos para poder compartirlos. Recuerden que utilizar fforce nunca es recomendable, salvo escasas excepciones, porque puede romper el sistema.

Primero tenemos que actualizar el sistema sin actualizar glibc, esto lo hacemos con

# pacman -Syu --ignore glibc

Una vez terminada la actualización, tenemos qué ver que paquetes todavía tienen archivos dentro de /lib

$ find /lib -exec pacman -Qo -- {} +

esto nos da una lista de los archivos que hay en /lib y a qué paquetes pertenecen

error: no puedo determinar el dueño del directorio '/lib'
/lib/libcidn.so.1 es propiedad de glibc 2.16.0-1
/lib/libpthread-2.16.so es propiedad de glibc 2.16.0-1
/lib/libnsl-2.16.so es propiedad de glibc 2.16.0-1
/lib/libnss_nisplus-2.16.so es propiedad de glibc 2.16.0-1
/lib/libnss_nis.so.2 es propiedad de glibc 2.16.0-1
error: no puedo determinar el dueño del directorio '/lib/systemd'
error: no puedo determinar el dueño del directorio '/lib/systemd/system'
/lib/systemd/system/httpd.service es propiedad de systemd-httpd-units 1.0-1
/lib/libnss_compat-2.16.so es propiedad de glibc 2.16.0-1
error: no puedo determinar el dueño del directorio '/lib/security'
/lib/security/pam_google_authenticator.so es propiedad de google-authenticator-libpam-hg 93-1
/lib/security/pam_face_authentication.so es propiedad de pam-face-authentication-svn 20110914-1
/lib/libpcprofile.so es propiedad de glibc 2.16.0-1
error: Ningún paquete posee /lib/modules/3.1.9-1-ARCH/modules.ofmap
error: Ningún paquete posee /lib/modules/3.1.9-1-ARCH/modules.ccwmap
error: Ningún paquete posee /lib/modules/3.1.9-1-ARCH/modules.usbmap
error: no puedo determinar el dueño del directorio '/lib/modules/3.2.0-1-ck'
error: no puedo determinar el dueño del directorio '/lib/modules/3.2.0-1-ck/misc'
error: Ningún paquete posee /lib/modules/3.2.0-1-ck/misc/vboxnetadp.ko
error: Ningún paquete posee /lib/modules/3.2.0-1-ck/misc/vboxnetflt.ko
error: Ningún paquete posee /lib/modules/3.2.0-1-ck/misc/vboxdrv.ko
error: no puedo determinar el dueño del directorio '/lib/modules/3.1.5-2-ck'
error: no puedo determinar el dueño del directorio '/lib/modules/3.1.5-2-ck/misc'

Lo siguiente es hacer una lista (y guardarla, para después poder reinstalarlos al finalizar la actualización) con los paquetes que tienen archivos en /lib, por ejemplo en la lista se ven los siguientes, claro que pueden ser distintos a estos.

google-authenticator-libpam-hg pam-face-authentication-svn systemd-httpd-units

Una vez armada la lista hay que eliminar esos paquetes, en caso de que algunos de los paquetes sea dependencia de otro hay que eliminar ese paquete también y agregarlo a la lista. En mi caso además de algunos paquetes con archivos tenía en /lib/modules/ muchos directorios creados por depmod para varias de las versiones que tuve del kernel.

Como ninguna de esas versiones correspondía al kernel que uso actualmente decidí eliminar completamente /lib/modules, aunque lo mejor sería mover el directorio completo al lugar que le corresponde ahora /usr/lib.

# mv /lib/modules /usr/lib/modules

Al llegar acá creí que estaba en condiciones de actualizar glibc, pero no fue así. La base de datos de pacman tenía otros paquetes con archivos dentro de /lib, esto lo comprobé mediante el siguiente comando

$ grep '^lib/' /var/lib/pacman/local/*/files

esto nos da una lista con los paquetes que tienen archivos dentro de /lib, en mi caso era parecida a esta

/var/lib/pacman/local/glibc-2.16.0-1/files:lib/
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/ld-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/ld-linux-x86-64.so.2
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libBrokenLocale-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libutil-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libutil.so.1
/var/lib/pacman/local/ld-lsb-3-3/files:lib/
/var/lib/pacman/local/ld-lsb-3-3/files:lib/ld-lsb.so.3
/var/lib/pacman/local/linux-ck-headers-3.2.1-3/files:lib/
/var/lib/pacman/local/linux-ck-headers-3.2.1-3/files:lib/modules/
/var/lib/pacman/local/linux-ck-headers-3.2.1-3/files:lib/modules/3.2.1-3-ck/
/var/lib/pacman/local/linux-ck-headers-3.2.1-3/files:lib/modules/3.2.1-3-ck/build
/var/lib/pacman/local/v4l2loopback-git-20120325-1/files:lib/
/var/lib/pacman/local/v4l2loopback-git-20120325-1/files:lib/modules/
/var/lib/pacman/local/v4l2loopback-git-20120325-1/files:lib/modules/3.2.12-1-ARCH/
/var/lib/pacman/local/v4l2loopback-git-20120325-1/files:lib/modules/3.2.12-1-ARCH/kernel/
/var/lib/pacman/local/v4l2loopback-git-20120325-1/files:lib/modules/3.2.12-1-ARCH/kernel/drivers/
/var/lib/pacman/local/v4l2loopback-git-20120325-1/files:lib/modules/3.2.12-1-ARCH/kernel/drivers/misc/
/var/lib/pacman/local/v4l2loopback-git-20120325-1/files:lib/modules/3.2.12-1-ARCH/kernel/drivers/misc/v4l2loopback.ko

Acá hay hacer lo mismo que antes, es decir, identificar qué paquetes, además de glibc, tienen archivos en /lib, guardar una lista con los nombres de esos paquetes y eliminarlos del sistema. En mi caso los paquetes son
v4l2loopback-git linux-ck-headers ld-lsb
Una vez desinstalados los paquetes anteriores, el comando grep ‘^lib/’ /var/lib/pacman/local/*/files debería mostrar solo archivos de glibc. Algo así

/var/lib/pacman/local/glibc-2.16.0-1/files:lib/
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/ld-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/ld-linux-x86-64.so.2
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libBrokenLocale-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libBrokenLocale.so.1
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libSegFault.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libanl-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libanl.so.1
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libc-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libc.so.6
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libcidn-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libcidn.so.1
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libcrypt-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libcrypt.so.1
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libdl-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libdl.so.2
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libm-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libm.so.6
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libmemusage.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libnsl-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libnsl.so.1
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libnss_compat-2.16.so
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libnss_compat.so.2
/var/lib/pacman/local/glibc-2.16.0-1/files:lib/libnss_db-2.16.so

Ahora estamos en condiciones de actualizar glibc

# pacman -Su

y todo debería salir bien, para comprobarlo ejecutamos

ls -ld /lib

y deberíamos obtener algo así

lrwxrwxrwx 1 root root 7 jul 7 07:09 /lib -> usr/lib

si pacman nos dice algo como esto

error: error al realizar la transacción (archivos en conflicto)
glibc: /lib existe en el sistema de archivos
Ocurrieron errores, no se actualizaron paquetes

Quiere decir que hicimos algo mal y hay otros paquetes, además de glibc, que contienen /lib entre su lista de archivos y hay seguir buscándolos

Espero que les sirva. Saludos!

Presentación y error en las locale

Hola! Soy Fernando. Un amante de la informática y el Software Libre. Programador mediocre y reparador obstinado. Por presión consejo de varios amigos decidí crear este blog para compartir mis experiencias informáticas.

Para empezar voy a contar como solucioné un extraño problema con el idioma de Gnome Shell. Hace unas semanas actualicé Gnome a la versión 3.4 en un Arch Linux que tengo instalado en un pendrive de 32GB. Actualicé con la esperanza de que desaparezca un bug que me impedía instalar extensiones de Gnome Shell. Lamentablemente el bug seguía ahí. Para probar si era un error de configuración de mi usuario creé una cuenta de prueba. Como era de esperar la cuenta de prueba no tenía ningún problema para instalar extensiones. Esto me demostraba que había un error en la configuración de mi usuario. Eliminé los archivos .(punto) que usa Gnome 3: ~/.config, ~/.dbus, ~/.gconf, ~/.gnome2 y ~/.local. Esto casi solucionó el problema de las extensiones pero trajo otro. La mitad de Gnome estaba en ingles.

Al comprobar la configuración de idioma en el Configuración de Sistema en idioma tenía seleccionado:
unspecified [ANSI_X3.4-1968]

Y al revisar el archivo ~/.xsession-errors estaba lleno de errores similares a este:
(process:6958): Gtk-WARNING **: Locale not supported by C library. Using the fallback 'C' locale.

Luego de días de infructuosa búsqueda por Internet, probé una solución que leí en un foro que debido al poco tiempo que tenía en ese momento y como me pareció que no era correcta había descartado. La solución consistía en habilitar todas las locale, descomentarlas en /etc/locale.gen. Para sorpresa mía, eso solucionó mi problema. Descomenté (a mano) cada una de las locale en el Arch Linux de mi pendrive, y las volví a generar. Al reiniciar el problema estaba solucionado. Mientras aún bebía el dulce vino de la victoria, me di cuenta de que tenía el mismo problema en el Arch Linux de mi pc de escritorio. Como descomentar a mano las locale me llevó casi cinco minutos, decidí usar el poder de la linea de comandos. Y les dejo los pasos para solucionarlo si les ocurre lo mismo.

Primero comentamos todas las locale que tengamos sin comentar. Luego, ejecutamos estos comandos para descomentar las locale y guardarlas en un archivo temporal llamado locale.gen.new
$ cat /etc/locale.gen | grep -v "##" | awk -v FS=\# '{ print $2 }' > locale.gen.new
Después de verificar que el archivo contenga las locale descomentadas y sobre todo que esté la que queremos usar,cambiamos los permisos y el usuario dueño del archivo creado
# chmod 644 locale.gen.new
# chown root:root locale.gen.new

Hacemos un backup de /etc/locale.gen
# mv /etc/locale.gen{,.bak}
y reemplazamos /etc/locale.gen con el que creamos
# cp locale.gen.new /etc/locale.gen
Luego generamos nuevamente las locale
# locale-gen
Ahora solo resta reiniciar, entrar a la configuración de idioma de Gnome 3, agregar el idioma correspondiente, reiniciar la sesión y listo.

Espero que mi experiencia sea de ayuda.

Saludos!