martes, 7 de febrero de 2012

Mejora a Logging por default en Django

La configuración por default de LOGGING de Django hace que no se muestren por consola los mensajes de logging generados, sólo muestra los requests, y hacer que se vean nuestros mensajes es bastante fácil, sólo hay que agregar a LOGGING (en settings.py) las líneas en negritas:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler'
        },
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler'
        },
    },
    'loggers': {
        '': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': True,
        },
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}

(esto funcionará en Django >= 1.3)

domingo, 5 de febrero de 2012

Mejorando listado de task en Fabric

Cuando al usar Fabric listamos los comandos disponibles con --list, este listado está restringido a un ancho de 75 caracteres. Pero al usar una terminal de 160 caracteres de ancho, es mucho el espacio desperdiciado, y la documentación "ocultada".

Hice unos cambios en Fabric para que, al listar los comandos, utilice todo el ancho disponible. Antes, con una columna de 160 caracteres, el listado se mostraba:


Available commands:


    FabricTest    Nose-oriented test runner which wipes state.env and provid...
    TestParallel
    eq_           Shadow of the Nose builtin which presents easier to read m...
    server        Returns a decorator that runs an SSH server during functio...


Ahora:


Available commands:

    FabricTest    Nose-oriented test runner which wipes state.env and provides file helpers.
    TestParallel
    eq_           Shadow of the Nose builtin which presents easier to read multiline output.
    server        Returns a decorator that runs an SSH server during function execution.


Estos cambios están disponibles en mi fork de Fabric y puede ser instalado ejecutando "pip install -e git+https://github.com/hgdeoro/fabric@1.3-hgdeoro#egg=fabric"


Fabric: unsupported operand type(s) for &: 'str' and 'int'

Me ocurrió que upload_template() de Fabric fallaba con el siguiente mensaje de error:

Fatal error: put() encountered an exception while uploading '<StringIO.StringIO instance at 0x7fb4b6e0e368>'


Underlying exception message:
    unsupported operand type(s) for &: 'str' and 'int'


Aborting.

Lo que estaba haciendo era bastante simple:

    upload_template(
        os.path.join('deploy-files', 'nginx', 'nginx-template.conf'),
        nginx_config_file_to,
        context=context,
        use_sudo=True, backup=False, mode='0644')


Pero claro, resulta que el modo debe ser un valor en OCTAL, y no un STRING! Cambiando el modo de string a octal solucionó el problema:

    upload_template(
        os.path.join('deploy-files', 'nginx', 'nginx-template.conf'),
        nginx_config_file_to,
        context=context,
        use_sudo=True, backup=False, mode=0644)


Es algo simple, pero lo comparto porque no encontré mucha información al buscar dicho mensaje de error en internet.



sábado, 4 de febrero de 2012

Nuevo "list format" para Fabric

He implementado un nuevo "list format" para Fabric. Este nuevo formateador hace que se muestren las distintas "tasks" declaradas, junto a la documentacion completa de las mismas.

Está disponibles en un branch de master (https://github.com/hgdeoro/fabric/tree/new_list_format_fulldoc) en un un branch de 1.3 (https://github.com/hgdeoro/fabric/tree/1.3-hgdeoro).

Por ejemplo, al ejecutar Fabric sobre "tests/test_parallel.py" con los argumentos "--list --list-format=fulldoc", se genera el siguiente listado:

Available commands:

    FabricTest
    ----------
        Nose-oriented test runner which wipes state.env and provides file helpers.

    TestParallel
    ------------

    eq_
    ---
        Shadow of the Nose builtin which presents easier to read multiline output.

    server
    ------
        Returns a decorator that runs an SSH server during function execution.
        Direct passthrough to ``serve_responses``.



Para instalarlo via pip:
$ pip install -e git+https://github.com/hgdeoro/fabric@1.3-hgdeoro#egg=fabric



Contribuyendo a proyectos OpenSource via GitHub

Hace tiempo uso GitHub para mis proyectos open source, pero hoy pude usarlo para compartir un pequeño FIX que hice a Fabric, y la verdad es que hace muy sencillo el trabajo.

El fix es algo insignificante (en una clase hay 2 métodos con el mismo nombre). Lo que hice fue renombrarlo el método, y después investigar qué tan fácil sería compartirlo con los autores de Fabric... y resultó muy fácil. Teniendo en cuenta que yo ya había clonado el proyecto (en modo solo-lectura), los pasos que seguí fueron:

  1. busqué en la doc. de GitHub cómo hacerlo, y lo encontré inmediatamente: http://help.github.com/send-pull-requests/
  2. creé un fork del proyecto original
    • esto se hace con 1 clic en la interfaz web de GitHub
  3. cambié el "remote" a mi fork
    • git remote set-url origin git@github.com:hgdeoro/fabric.git
  4. creé un branch
    • git branch fix_duplicated_test_method
  5. realicé el commit con las modificaciones
  6. hice el push
    • git push origin fix_duplicated_test_method:fix_duplicated_test_method
  7. en la interfaz web de GitHub me cambié al branch fix_duplicated_test_method
  8. en la interfaz web de GitHub hice clic en "Pull Request"  y cargué el mensaje
El pull request puede verse aqui: https://github.com/fabric/fabric/pull/549/files

Samba4 en CentOS 6.2


Siguiendo los pasos de https://wiki.samba.org/index.php/Samba4/HOWTO, con un CentOS 6.2 recién instalado, estos son los pasos que seguí para instalar Samba 4:

Preparacion del entorno
  • crear usuario para NO trabajar con root, configurar keys de ssh y sudo
  • instalar paquetes básicos
# curl -o epel-release-6-5.noarch.rpm \
    http://download.fedora.redhat.com/pub/epel/6/i386/epel-release-6-5.noarch.rpm
# sudo rpm -i epel-release-6-5.noarch.rpm
# sudo yum install -y man
# sudo yum install -y gcc patch
# sudo yum install -y autoconf

Compilado de Samba 4
  • instalamos git
# sudo yum install -y git

  • instalamos paquetes recomendados
$ yum install libacl-devel libblkid-devel gnutls-devel readline-devel python-devel gdb pkgconfig
$ yum install gtkhtml setroubleshoot-server setroubleshoot-plugins policycoreutils-python libsemange-python setools-libs-python setools-libs popt-devel libpcap-devel sqlite-devel libidn-devel libxml2-devel libacl-devel libsepol-devel libattr-devel keyutils-libs-devel zlib-devel cyrus-sasl-devel

Al instalarlos con el comando anterior, me apareció:

(...)
No package gtkhtml available.
No package libsemange-python available.
(...)

pero me imagino que no son paquetes esenciales...
  • bajamos repositorio Git y compilamos
# git clone git://git.samba.org/samba.git samba-master
# cd samba-master

Ahora deberemos "parchear" unos scripts Python que tienen un bug (esto no hará falta cuando los arreglos a estos scripts estén en git). Para parchearlos hay que ejecutar (en una misma línea):

# curl -s https://raw.github.com/gist/1739239/a8a38ef99dae9c5a12bc6939d59161dcc1f2fa5a/use-named-argument-dir-instead-of-prefix.diff | patch -p1 

Este comando fallará si los scripts fueron arreglados en el repositorio de Git (al menos los parches ya fueron aceptados :-D  https://lists.samba.org/archive/samba-technical/2012-February/081527.html).

Ahora continuamos con el proceso:

# ./configure.developer --prefix=/opt/samba4-3bea5a147b

Nota: '3bea5a147b' es el commit (abreviado) de Git, sirve para identificar exactamente que versión estamos instalado. Se obtiene ejecutando: `git log --oneline | head -n 1 | cut -d " " -f 1`

# make -j2
# sudo mkdir /opt/samba4-3bea5a147b
# sudo chown USUARIO /opt/samba4-3bea5a147b
# make install

El próximo paso sería generar los archivos básicos que necesita Samba para funcionar. Esto se hace con el script "provision", pero al parecer al algún problema con el último comando que ejecutamos ("make install"): éste modifica algunos archivos y hace que se produzca un error al intentar ejecutar "provision". Por lo tanto, antes de ejecutar "provision", debemos volve a ejecutar "make" (https://lists.samba.org/archive/samba-technical/2012-February/081526.html)

# make -j2
# sudo ./source4/setup/provision \
    --realm=samdom.example.com \
    --domain=SAMDOM \
   --adminpass=SOMEPASSWORD \
   --server-role='domain controller'

Listo! Ya tenemos Samba4 instalado en /opt. Ahora queda lanzar el proceso:

# sudo /opt/samba4-3bea5a147b/sbin/samba -i -M single
Aunque Samba ya está andando, queda pendiente su configurar, configuración de DNS, etc.


EDITADO:  siguiendo el consejo del HOWTO, hace falta agregar el dominio en /etc/resolv.conf (una linea al estilo de "domain samdom.example.com")


EDITADO:  el password seteado con "--adminpass" no debe ser simple, sino el proceso fallará con el error "check_password_restrictions: the password does not meet the complexity criteria!".



Corriendo tests con instancia de PostgreSql en ram

Otra manera de optimizar la ejecución de tests de Django, pero SIN modificar la instalación de PostgreSql del sistema operativo es crear una nueva instancia, corriendo totalmente en ram.

Para crear una nueva instancia usamos initdb:

$ /usr/lib/postgresql/9.1/bin/initdb \
    --pgdata=/dev/shm/pgtesting \
    -U horacio

Y para lanzar la instancia en segundo plano:


$ /usr/lib/postgresql/9.1/bin/postgres \
    -F -i -p 5444 -S $((1024*64)) \
    -D /dev/shm/pgtesting \
    --unix_socket_directory=/dev/shm/pgtesting \
    -r /dev/shm/pgtesting/postgresql.log &


Luego creamos el usuario y BD para la aplicación Django:

psql -h 127.0.0.1 \
    -c "create user vindler with password 'x' superuser" postgres
psql -h 127.0.0.1 \
    -c "create database vindler owner vindler" postgres


Mejora en tiempos de ejecución de test: 28%

La ejecución de los tests con PostgreSql en disco, con las optimizaciones de mi artículo anterior tardan alrededor de 7 segundos:


Ran 18 tests in 7.071s
5.44user 0.58system 0:10.40elapsed 57%CPU (0avgtext+0avgdata 122880maxresident)k
0inputs+1184outputs (0major+16964minor)pagefaults 0swaps


Ran 18 tests in 6.843s
5.28user 0.65system 0:10.27elapsed 57%CPU (0avgtext+0avgdata 122976maxresident)k
0inputs+1176outputs (0major+16956minor)pagefaults 0swaps


Ran 18 tests in 7.032s
5.42user 0.64system 0:10.42elapsed 58%CPU (0avgtext+0avgdata 124304maxresident)k
0inputs+1168outputs (0major+17122minor)pagefaults 0swaps


Los mismos tests ejecutandose en la nueva instancia de PostgreSql totalmente en ram, tardan alrededor de 5 segundos:


Ran 18 tests in 5.220s
4.41user 0.65system 0:08.38elapsed 60%CPU (0avgtext+0avgdata 117904maxresident)k
8inputs+1176outputs (0major+16524minor)pagefaults 0swaps


Ran 18 tests in 5.047s
4.32user 0.53system 0:08.04elapsed 60%CPU (0avgtext+0avgdata 117888maxresident)k
0inputs+1168outputs (0major+16504minor)pagefaults 0swaps


Ran 18 tests in 4.665s
3.95user 0.64system 0:07.79elapsed 58%CPU (0avgtext+0avgdata 117856maxresident)k
0inputs+1176outputs (0major+16502minor)pagefaults 0swaps



Al ejecutar los tests de stress: 33%

Con PostgreSql en disco:


Ran 1 test in 24.601s
15.21user 2.72system 0:27.98elapsed 64%CPU (0avgtext+0avgdata 130944maxresident)k
0inputs+9616outputs (0major+18298minor)pagefaults 0swaps


Ran 1 test in 24.458s
15.16user 2.51system 0:27.57elapsed 64%CPU (0avgtext+0avgdata 131488maxresident)k
472inputs+9608outputs (0major+18457minor)pagefaults 0swaps


Ran 1 test in 24.552s
15.23user 2.63system 0:27.95elapsed 63%CPU (0avgtext+0avgdata 131088maxresident)k
232inputs+9616outputs (0major+18310minor)pagefaults 0swaps

Con PostgreSql en ram:

Ran 1 test in 16.082s
11.30user 2.46system 0:19.22elapsed 71%CPU (0avgtext+0avgdata 126080maxresident)k
0inputs+9616outputs (0major+17675minor)pagefaults 0swaps

Ran 1 test in 15.736s
11.25user 2.20system 0:18.82elapsed 71%CPU (0avgtext+0avgdata 126192maxresident)k
0inputs+9608outputs (0major+17684minor)pagefaults 0swaps

Ran 1 test in 15.408s
10.78user 2.27system 0:18.44elapsed 70%CPU (0avgtext+0avgdata 126384maxresident)k
0inputs+9608outputs (0major+17693minor)pagefaults 0swaps



Acelerando tests de Django con PostgreSql

La ejecucion inicial de los tests toma aproximadamente 15 segundos:

4.54user 0.64system 0:15.25elapsed 34%CPU (0avgtext+0avgdata 123600maxresident)k
4.70user 0.54system 0:14.70elapsed 35%CPU (0avgtext+0avgdata 122992maxresident)k
4.46user 0.65system 0:14.85elapsed 34%CPU (0avgtext+0avgdata 122912maxresident)k

Luego de ajustar los siguientes parametros:
- fsync = off
- synchronous_commit = off
- wal_sync_method = fsync

la ejecución toma aproximadamente 8.5 segundos:

4.22user 0.56system 0:08.62elapsed 55%CPU (0avgtext+0avgdata 123024maxresident)k
4.32user 0.58system 0:08.97elapsed 54%CPU (0avgtext+0avgdata 123008maxresident)k
4.29user 0.50system 0:08.74elapsed 54%CPU (0avgtext+0avgdata 123040maxresident)k

El tiempo se redujo casi a la mitad! Aunque esta configuración no es para nada recomendable para un equipo de producción, creo que vale la pena para ejecutar tests.

jueves, 2 de febrero de 2012

Bajar paquetes y no instalarlos con yum

Suelo usar en Debian/Ubuntu el comando:


# aptitude -yd algun-paquete

que permite bajar el paquete pero NO instalarlo. Pero yum no tiene ninguna opción parecida, aunque encontré que a través de un plugin se puede conseguir la misma de aptitude.

Para instalar dicho plugin:

# yum install yum-downloadonly


# yum --help
(...)
  Plugin Options:
    --downloadonly      don't update, just download
    --downloaddir=DLDIR
                        specifies an alternate directory to store packages

Y se puede usar, por ejemplo:

# yum install --downloadonly python-devel

Las instrucciones las encontré en http://www.cyberciti.biz/faq/yum-downloadonly-plugin/

miércoles, 25 de enero de 2012

Instalando django_openid_auth usando PIP

Hay algunos problemas con la version 0.4 de django_openid_auth (ej: no se puede instalar via pip). El proyecto es open source, por lo tanto es muy facil subirlo a GitHub y compartir estos arreglos :-)

Básicamente bajé el proyecto original (revisión 88) y lo subi a GitHub. Para instalarlo usando PIP hay que ejecutar:

./pip install -e git+http://github.com/hgdeoro/hgdeoro_fork_of_django_openid_auth#egg=django_openid_auth

Actualización

Mucho mejor, instalamos usando PIP, pero un commit en particular (ec68dfc046d1a75b50080ea98c56eda71956ed7a):

pip install -e git+http://github.com/hgdeoro/hgdeoro_fork_of_django_openid_auth@ec68dfc046d1a75b50080ea98c56eda71956ed7a#egg=django_openid_auth

O también un tag en particular (bzr_revno_88):

pip install -e git+http://github.com/hgdeoro/hgdeoro_fork_of_django_openid_auth@bzr_revno_88#egg=django_openid_auth


miércoles, 21 de diciembre de 2011

Cargando modulo 'tun' al iniciar Android

Al intentar usar el cliente de OpenVpn me encontré con que mi Android no carga automáticamente el modulo "tun", y por lo tanto la VPN nunca levanta.

Para solucionarlo, agregué el siguiente archivo en "/system/etc/init.d/10modprobetun":

Luego de crear el archivo, hace falta agregarle permisos de ejecución, usando:

chmod +x /system/etc/init.d/10modprobetun

Para poder modificar los contenidos de /system, hay que remontarlo en modo escritura, usando:

mount -o remount,rw /system


Ahora, luego de reiniciar el celular, el modulo aparece cargado:


localhost ~ # lsmod 
Module                  Size  Used by    Not tainted
wireless              189315  0
tun                    11765  0

jueves, 8 de diciembre de 2011

Aprendiendo a usar uci en OpenWrt

Entre la extensa documentación de OpenWrt encontré que "uci show" puede ser de muchísima ayuda, ya que hace un "dump" de la configuración en un formato que después se puede usar con "uci get" y "uci set". Por ejemplo:


root@TL_MR3420:/etc/config# uci show system
system.@system[0]=system
system.@system[0].timezone=UTC
system.@system[0].hostname=TL_MR3420
system.ntp=timeserver
system.ntp.server=0.openwrt.pool.ntp.org 1.openwrt.pool.ntp.org 2.openwrt.pool.ntp.org 3.openwrt.pool.ntp.org
system.led_usb=led
system.led_usb.name=USB
system.led_usb.sysfs=tp-link:green:3g
system.led_usb.trigger=usbdev
system.led_usb.dev=1-1
system.led_usb.interval=50

Luego, por ejemplo, para cambiar la zona horaria:

root@TL_MR3420:/etc/config# uci set system.@system[0].timezone=ART3
root@TL_MR3420:/etc/config# uci commit system

sábado, 5 de noviembre de 2011

Apache en primer plano (o sea, foreground)

Necesitaba iniciar apache y que quede funcionando en "primer plano". Inicialmente intenté arrancarlo con la opción "-X" para activar el modo debug, pero esto hacía que las páginas sean servidas muy lentamente. Buscando un poco más encontré http://httpd.apache.org/docs/2.2/programs/httpd.html y ví que se puede usar "-D" para lograrlo.

Finalmente, el comando que estoy usando es:


apache2 -DNO_DETACH -DFOREGROUND -f apache-dev.conf


lunes, 31 de octubre de 2011

CyanogenMod 7.1 en mi LG Optimus One (P500)

Pude instalar exitosamente CyanogenMod 7.1 (Android 2.3 Gingerbread) en mi LG Optimus One (P500), usando un ROM no oficial (o sea un ROM que no es armado por el proyecto CyanogenMod). Mi celular tenía originalmente Android 2.2 (Froyo). El link con todas las instrucciones, advertencias, consejos, etc. es:

http://forum.xda-developers.com/showthread.php?t=946354

Mi intención con este post es compartir mi experiencia, nada más. Si vas a hacerlo, te recomiendo que sigas las instrucciones del link que puse más arriba.

Yo use la version "beta6.5.8", que era la versión estable del ROM.

Procedimiento que seguí:
  • Primero: investigar en internet los peligros de hacer esto! Lo peor que puede pasar es que el celular deje de funcionar (o sea, ni siquiera se pueda prender)! Además, los programas que vienen de fábrica puestos por LG no van a estar mas (NDrive, juegos, y la posibilidad de sincronizar los datos con la PC usando el soft de LG, etc, etc, etc). A mí esto no me afectaba porque no uso esos programas, y la sincronización la hago con Google.
  • Leer http://forum.xda-developers.com/showthread.php?t=946354 (allí están todas las instrucciones necesarias).
  • Backupear todos los datos importantes, sacar todas las fotos, downloads, etc. 
  • Antes de la instación tuve que rootearlo (no entiendo por qué Google no obliga a que todos los celulares salgan rooteados "de fábrica", o con algún procedimiento documentado para hacerlo). Lo rooteé exitosamente con GingerBreak-v1.20.
  • Luego instalé ClockworkMod ROM Manager (http://www.clockworkmod.com/rommanager): esto permite hacer un backup de la instalación original e instalar ROMs. Este programa de la opción de formatear la tarjeta SD para crear una partición ext2/ext3, swap, etc. Si se hace esto, se perderán los datos almacenados en la tarjeta SD.
  • Luego hice un backup del ROM original (Froyo), por las dudas... Y por las dudas lo bajé a la PC.
  • Luego bajé el ROM para hacer la actualización, en mi caso, la versión estable más reciente era la beta6.5.8. El link actualizado a la última versión estable está en http://forum.xda-developers.com/showthread.php?t=946354
  • Luego de bajar el archivo, hay que pasarlo a la tarjeta SD.
  • En el Android, abrir "Rom Manager", elejir "Intall ROM from SD Card", y elegir el archivo bajado en el punto anterior. Lo que recomiendan es "... Do not forget to wipe data/cache ...", así que yo elegí borrar todo (total no tenía datos importantes en el celular).
  • A esta altura, el celular se reiniciará, instalará la nueva versión y arrancará nuevamente.
  • Luego hace falta instalar un ROM que trae las aplicaciones de Google mínimas necesarias (por ejemplo, Market!). El link para bajar las apicaciones también está en http://forum.xda-developers.com/showthread.php?t=946354
  • Ahora ya podemos abrir Market y bajar las aplicaciones que necesites :-)

    domingo, 23 de octubre de 2011

    Aptitude no funciona con multiarch

    Ubuntu Oneiric activa el soporte para multiarch.
    Multiarchi: Integrate support for cross-architecture installation of binary packages (particularly i386 / amd64, but also other combinations) in dpkg and apt
    Esto produce que aptitude sea bastante inusable debido a varios bugs (831768828807845183) que, al dia de hoy parecen estar sin resolver. Probé desactivar multiarch y al menos aptitude ya me funciona como antes. Para desactivar multiarch, edité el archivo /etc/dpkg/dpkg.cfg.d/multiarch y comenté la única linea que tiene:

    Antes:
    foreign-architecture i386

    Ahora:

    #foreign-architecture i386

    Al menos ya no me causa problemas al instalar nuevos paquetes, y ya no tengo conflictos imposibles de resolver (831768).

    ----------

    Luego de desactivar multiarch, no me funciona Wine, asi que simplemente no usaré aptitude, y estaré obligado a usar apt-get, o synaptic :-(

    Estilos de app. Gtk al usar KDE

    Por alguna cuestion la integración del estilo de las aplicaciones GTK (por lo tanto las app. Gnome) no está funcionando al usar KDE en Ubuntu Oneiric.

    Encontré una alternativa en https://bbs.archlinux.org/viewtopic.php?id=121803. Tampoco funcionó. Pero luego de revisar los estilos con soporte para GTK3, encontré que el estilo "oxygen-gtk" no existe en /usr/share/themes... Asi que probé con "Radiance" (que existe y es para GTK3) y funcionó! :-)

    Luego de hacer unas modificaciones, este es el contenido que dejé en /etc/gtk-3.0/settings.ini.

    [Settings]
    gtk-theme-name = Radiance
    gtk-fallback-icon-theme = gnome
    gtk-application-prefer-dark-theme = false
    gtk-font-name = Sans 9

    Y ahora queda pendiente arreglar las aplicaciones GTK2. Al parecer, las aplicaciones GTK2 buscan un archivo ".gtkrc-2.0" en el home del usuario, pero KDE genera un archivo llamado ".gtkrc-2.0-kde4". Esto puede solucionarse creando un symlink en el home del usuario con el siguiente comando:

    ln -s .gtkrc-2.0-kde4 .gtkrc-2.0

    sábado, 22 de octubre de 2011

    Ubuntu Oneiric + Arduino 0.22 = problemas

    Luego de actualizar Ubuntu ya no me compiló un proyecto de Arduino. Luego de chequear en internet encontré que hay unos bugs relacionados a este problema:

    https://bugs.launchpad.net/ubuntu/+source/binutils-avr/+bug/818188
    https://bugs.launchpad.net/ubuntu/+source/avr-libc/+bug/791335
    http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634341
    http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=633659

    Y la forma rápida de solucionarlo fue seguir el consejo del último de los links, editando el archivo hardware/arduino/cores/arduino/wiring.h (dentro del directorio donde tengo instalado Arduino 0.22) y comentando la linea 79:

    Inicialmente está así:

    #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))

    y ahora:

    // #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))

    No sé cuáles serán los "efectos colaterales" pero funcionó!

    miércoles, 19 de octubre de 2011

    Cómo resetear South

    Podemos resetear South desinstalándolo y volviéndolo a instalar. Atención: esto hará que se pierdan todas las migraciones existentes, y los datos de las BD de las aplicaciones que se quieran resetear. Los pasos a seguir son:

    1) eliminar de la BD las tablas de South: south_migrationhistory.
    2) eliminar de la BD las tablas de las aplicaciones administradas por south.
    3) eliminar el paquete migrations de las aplicaciones que usen South.
    4) ejecutar syncdb.
    5) volver a marcar las aplicaciones que deben ser administradas usando South, ejecutando: "manage.py convert_to_south APP"


    lunes, 26 de septiembre de 2011

    PHP ejecutados al ser accedidos con WebDav

    Seguí las instrucciones para configurar WebDav en Apache2 (Ubuntu Server 10.04.3 LTS), pero las páginas de PHP eran "ejecutadas" al ser bajadas desde el editor HTML. La configuración (obviando la restricción por IP y usuario/password) era:

        Alias /edit /var/www/www.example.com
        <Location /webdav>
            DAV On
            ForceType text/plain
        </Location>
    

    Revisando la configuración de Apache ví que PHP era habilitado usando "SetHandler", así que lo solucioné usando "SetHandler None":

        Alias /edit /var/www/www.example.com
        <Location /webdav>
            DAV On
            ForceType text/plain
            SetHandler None
        </Location>
    


    jueves, 1 de septiembre de 2011

    Desabilitando GDM al inicio

    En Ubuntu 11.04 los servicios los arranca Upstart, así que para deshabilitar GDM no se puede borrar el link de /etc/rc2.d/gdm. La forma de hacerlo es editar /etc/init/gdm.conf y agregar "and runlevel RUNLEVEL=5" a la opción "start on". El diff es:


    --- a/init/gdm.conf
    +++ b/init/gdm.conf
    @@ -7,6 +7,7 @@ description     "GNOME Display Manager"
     author         "William Jon McCann "

     start on (filesystem
    +          and runlevel RUNLEVEL=5
               and started dbus
               and (drm-device-added card0 PRIMARY_DEVICE_FOR_DISPLAY=1
                    or stopped udev-fallback-graphics))