Posts etiquetados como ‘Universidad’

Cacharreando…

Sábado, septiembre 17th, 2011

Se termina el verano…

…pero no por ello uno deja una de sus aficiones: ¡cacharrear!
Hace unos días estuve hablando con un colega del grado, y comencé a buscar piezas que tenía por un trastero (simplificando), de habérselas cambiado a mi sobremesa a lo largo de los años, y resulta que tenía componentes suficientes para hacer un PC “nuevo”. Bueno, me faltaba un disco duro, pero le pude quitar un viejo IDE que ya no estaba conectado, sino tan solo atornillado, a la caja del sobremesa.
Me sorprendió gratamente también encontrar una caja y PSU usadas, y tras ensamblar todo y un par de cortecitos en los dedos por la mierdachapa de la que está hecha, intenté arrancarlo, ¡y arrancó!
Lo malo es que no tenía lector de CD/DVD (bueno, sí que tenía, pero me daba mucha pereza probar cuál funcionaría), así que me busqué otro sistema para bootear un SO.
No me costó mucho pensar en PXE, pues lo veo todos los días en la Facultad de Informática.

Como tengo un portátil funcionando, con Mac OS X (que al fin y al cabo es un UNIX: SUS03-compliant), podía montar ahí los servidores de tftp y de dhcp.

Instrucciones para activar tftp en Mac OS

Mac OS X ¡incluye! un servidor TFTP, aunque deshabilitado por defecto, y corre bajo los servicios de red (un inetd), no como servicio independiente. La forma de habilitarlo es la habitual en los servicios de Mac OS: cambiar una propiedad en un plist.
tl;dr: Hay que cambiar el fichero /System/Library/LaunchDaemons/tftp.plist como root y cambiar la -probablemente- sexta línea, en donde dice <true/> poner <false/>. (Disabled: false)
Tras esto, un $ sudo launchctl load /System/Library/LaunchDaemons/tftp.plist debería de levantar el servicio (aunque no aparecerá con ps).

Instrucciones para el servidor dhcp en Mac OS

Como suelo hacer, comencé por bajarme la última versión del dhcpd (la 4.2.2), pero esta, con soporte de DHCPv6, requiere unos símbolos definidos que Lion (10.7.1) no tiene en sus cabeceras (relativas precisamente al soporte de IPv6), así que para no complicarme me bajé una versión más antigua (la 3.1.3) que compiló sin problema alguno. Nota no importante: Archlinux también sigue con un paquete viejo de dhcpd por lo “complicado”, dicen ellos, que está siendo todavía dar soporte a dhcp4.
Os incluyo el fichero de configuración dhcpd.conf para arancar con PXE.
option domain-name "silice.lan";
option domain-name-servers ns1.silice.lan;
option subnet-mask 255.255.255.0;
default-lease-time 300;
max-lease-time 900;
ddns-update-style ad-hoc;
server-name "silice";
subnet 192.168.55.0 netmask 255.255.255.0 {
range 192.168.55.200 192.168.55.253;
filename "/tftpboot/pxelinux.0";
option routers 192.168.55.1;
}

Para lanzar dhcpd, en lugar de compilarlo y make install, yo solo lo compilé (make), y luego me creé un script para evitar tener que andar con ficheros de configuración en /etc, porque el dhcpd solo lo voy a usar para arrancar por PXE, ¡mi portátil no va a ser un servidor DHCP habitualmente!
El script:
#!/bin/bash
# Script to power up the DHCP server here.
cd ./dhcp-3.1.3/work.darwin/server
./dhcpd -f -cf dhcpd.conf -lf ./leases en0

Hay que ejecutarlo como root, pues DHCP utiliza un puerto inferior al 1024.

Arrancando…

Metí en el servidor TFTP (en /private/tftpboot/) las los elementos que coinciden con la expresión /boot/* y /boot/syslinux/*
Yo hice esto con la distro de Archlinux.
Bueno, pues con la distro de Archlinux os ahorrais probar, a menos que lo arranqueis desde un arch con el paquete archboot para arranque remoto. En mi instalación, después de descomprimir initramfs el kernel solicitaba lo que faltaba a un nbd0 (un Linux Network Block Device, algo que en el Mac no tenía)
Luego encontré y pude bajarme la imagen archboot, que sí tiene un initramfs autocontenido: en cuanto se carga eso no necesita soporte de ninguna entidad externa para su funcionamiento.
Una vez con esta imagen, ya pude por fin partir el disco e instalar Arch. Decidí, no obstante, partir el disco según el nuevo formato GPT, con una partición de 100M para /boot, otra de 2G para swap y lo restante repartido entre home y /.
Haber usado el esquema GPT impidió una correcta instalación automática de GRUB2, con lo que tuve que hacer la típica jaula chroot para instalar Grub desde dentro de ella, arrancando desde el Live.
Para instalar Grub hay que recordar montar /boot desde dentro del chroot, o grub-bios_setup no sabrá que son particiones diferentes!
Y con esto ya tenemos el sistema base montado.

Voy a aprovechar aquí para comentaros cuáles son las características del equipo que he conseguido montar.

  • Placa base: ASUS A8N32-SLi Deluxe (con 2x Gigabit Ethernet: 1x Marvell Yukon, 1x nVidia Ethernet)
  • CPU: AMD Athlon64 3200+ (Socket 939, sin soporte de paravirtualización) @2.00GHz, 1 core
  • RAM: 1.5 GB SODIMM DDR
  • HDD Sistema (/dev/sda): Seagate Barracuda 7200.9 (IDE/ATAPI) 300 GBytes (10^9 Bytes)
  • HDD Almacenamiento (/dev/sdb): Western Digital Caviar Green 3TB Advanced Drive Format (SATA3 6Gb/s)

Uno de los integrados de la RAM es erróneo, y produce errores y fallos de segmentación en momentos no predecibles. Esto se ha solucionado con la directiva badram de Grub 2 después de realizar un Memtest86+ para encontrar los sectores incorrectos.

Git y svn (Tutorial básico)

Sábado, enero 8th, 2011

He aquí un post bastante técnico. Para ver el “cómo hacerlo funcionar ya”, id hasta el final ;)

Ahora están bastante de moda los sistemas de control de versiones distribuidos, como Git, Mercurial y Bazaar.

No obstante, muchos de nosotros trabajamos en proyectos que, por unas circusntancias u otras utilizan sistemas de control de versiones centralizados.

En mi caso, en la Facultad de Informática de A Coruña tenemos montado un repositorio svn para algunas asignaturas.

SVN “está bien” (según sus defensores), pero según mi humilde opinión, Git lo supera por mucho en bastantes cosas. La primera, que es descentralizado.
He comenzado utilizando Git y por tanto no sé cómo podría hacerse lo que voy a decir con Mercurial o Bazaar; pero esto va a ser, a partir de aquí, un pequeño tutorial de como utilizar git, y como utilizar git con un repositorio svn. Esto está enfocado a sistemas POSIX, aunque la mayor parte es aplicable a la instalación de Git para Windows.

Aviso: Todos los comandos de git tienen entrada en el Manual, y muy buena; a diferencia de los comandos de Subversion, que solo te dicen que si quieres algo vayas a su web.

Para ver la documentación de un comando de git, se pueden hacer dos cosas:

  • o bien preguntárselo elegantemente a git: git init --help
  • o bien acceder directamente al manual, así: man git-init (con un guión en el medio)

La documentación de Git se encuentra en la sección 1 del manual.

Update: Vistas ciertas visitas desde Google, añado lo siguiente aquí como referencia rápida

En git es muy común estar haciendo commits continuamente. Porque como son locales, así se puede tener un control más fino de lo que se está cambiando.
Pero normalmente uno no quiere subir todos esos commits como tales a SVN, sino en su lugar, subir uno con el contenido ya hecho y funcional.

Esto puede lograrse del siguiente modo:

git branch miRamaDesarrollo
# Hacemos cambios al código..
git commit -m “Cambios triviales”
# Más cambios..
git commit -m “Mi gato me ha dado una idea genial para esto”
# Más cambios..
git commit -m “Seguro que ahora ya funciona”

Y cuando todo esté finalizado, para subirlo a SVN, cambiar a la rama master (o a donde lleves tus commits de SVN) y hacer:

git checkout master
git merge –squash miRamaDesarrollo

Esto crea un estado en el INDEX equivalente a hacer un merge de miRamaDesarrollo en master, pero sin hacer el merge, ni actualizar master. En este momento, se puede hacer un git commit para realmente generar un único commit con todos los cambios conjuntos de miRamaDesarrollo.
Luego, un git svn dcommit soluciona la tarea de enviar ese único commit.

Recordad, antes de volver a trabajar en la rama de desarrollo, hacer un git rebase master, para no generar un octopus.

Comandos básicos de Git

git init [-q] [--bare] [--shared=[<permissions>]] [directory]
Crea un repositorio vacío o reinicializa uno que ya exista. Lista de parámetros:

–bare
Crea un repositorio desnudo. Es decir, sin working tree.

Con SVN no vamos a utilizar este comando.

git add [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p] [--edit | -e] [--all | [--update | -u ]] [--intent-to-add | -N] [--refresh] [--ignore-erors] [--ignore-missing] [--] [<filepattern>...]
Este comando, con la cantidad de flags opcionales que tiene, actualiza el index utilizando el contenido actual del working tree para preparar el contenido en fase de ser versionado.Podeis ver todo lo que se añade y cómo funciona en la págian de manual (puede estar en inglés).

Generalmente se utilizará como git add <files>

git commit [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run] [(-c | -C) <commit>] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--status | --no-status] [--] [[-i | -o]<file>…]

Envía los contenidos del index a un nuevo commit, junto con un mensaje de log con el que el usuario describe los cambios.

El contenido a enviar puede especificarse de los siguientes modos:

  1. utilizando git add para añadir incrementalmente cambios al index antes de utilizar el comando commit (Nota: los archivos modificados deben ser añadidos explícitamente)
  2. utilizando git rm para eliminar archivos del working tree y del index, de nuevo, antes de utilizar el comando commit
  3. listando ficheros como argumentos al comando commit, en cuyo caso el commit ignorará los cambios del index y en su lugar grabará como contenido únicamente los cambios que ocurriesen en los ficheros pasados por parámetro y que ya deben ser conocidos para git (es decir, existían en el commit anterior)
  4. utilizando el switch -a con el comando commit para añadir automáticamente todos los cambios de los archivos ya conocidos (i.e., todos los archivos que están listados en el index) y para borrar automáticamente en el index todos los ficheros que hayan sido borrados del working tree, realizando inmediatamente el commit. (Este es el funcionamiento más parecido a svn commit)
  5. utilizando el switch --interactive con el comando commit para decidir uno a uno, qué archivos deberían ser parte del próximo commit, antes de finalizar la operación. Actualmente esto se implementa llamando primero a git add --interactive.

Si haces un commit y encuentras un error en lo que hiciste inmediatamente después, puedes recuperarlo utilizando git reset.

Podeis ver la lista de opciones en el manual, pero yo querría destacar --amend que nos permite editar el mensaje de log del último commit. Esto no debe hacerse jamás con un commit que haya sido subido (y posiblemente descargado por otra persona), o subido a un svn; pero mientras sean tus cambios privados, git te permite cambiar el log sin problema ninguno. Nota: Esto cambia el CommitID (un registro interno de Git que dice qué commit es padre de cuál).

git mv; git rm
Permiten mover y borrar ficheros. Lo mejor de utilizar esto en lugar de los comandos de las Coreutils, mv y rm es que el cambio se incluye automáticamente en el index. Además git rm permite opciones como [-f | --force] [-n] [-r] [--cached] [--ignore-unmatched] [--quiet]
git fetch
Probablemente no tengais que utilizar esta opción directamente. Se usa para bajarse objetos de un repositorio Git. Pero suele ser más útil que Git lo utilice dentro de comandos como git merge y git rebase
git rebase [-i | --interactive] [options] [--onto <newbase>] &lt:upstream> [<branch>]
git rebase –continue | –skip | –abort

git rebase <base> cambia el commit padre del conjunto de commits nuevos para que sea <base>. Se ve mejor en el ejemplo del manual; digamos que sirve para mantener la “raíz” de tu conjunto de cambios actualizada, si alguien hace un cambio por el medio.

Si la nueva base incluye cambios en ficheros que tú también has modificado habrá que resolver los conflictos antes de terminar. Hay un ejemplo de cómo en el manual. Cuando se haya resuelto un conflicto, git rebase --continue permite seguir con el proceso de rebase. Si uno no quiere tener que resolver conflictos, puede abortar el proceso con git rebase --abort

git merge [-n] [--stat] [--no-commit] [--squash] [-s &t;strategy>] [-X <strategy-option>] [--[no-]-rererere-autoupdate] [-m <msg>] <commit>…
git merge <msg> HAD <commit>…
Incorpora los cambios de un commit con nombre (generalmente una rama) en la rama actual. Se puede crear lo que se llama un “metacommit de mezcla” (merge commit) indicando cuáles eran los padres del commit mezclado
Son intersantes las siguientes opciones:

–commit, –no-commit
Hacer o no, directamente el commit cuando acabe de mezclar las ramas.
–ff, –no-ff
No genera un commit de mezcla si esta puede resolverse como un fast-forward (avance simple en la historia), solo actualiza el puntero de rama para que apunte al último commit. Este es el comportamiento por defecto.
Con –no–ff se genera un commit de mezcla aunque se pudiese resolver como un fast-forward.
–squash
Recrea el working tree y el estado del index como si hubiese ocurrido un merge real, pero no hace el commit, ni mueve HEAD, ni hace que el siguiente comando de git commit cree un commit de mezcla. Esto permite crear un único commit sobre la rama actual cuyo efecto es equivalente a mezclar la otra rama.
–ff-only
Evita mezclas a menos que HEAD esté actualizado o el merge se pueda resolver como un fast-forward.

Comprobaciones anteriores a la mezcla

Antes de aplicar cambios externios, deberías de comprobar que tu trabajo es correcto y se le ha hecho un commit, para que así no ocurran cosas extrañas si hay conflictos.

git log [<options>] [<since>..<until>] [[--] <path>…]
Muestra los logs de uno o más commits. Por ejemplo, git log HEAD~4 muestra todos los cambios desde hace cuatro commits hasta los cambios locales que aún no se han enviado. git log HEAD~4..HEAD muestra los cambios desde hace cuatro commits hasta el último, desechando lo que haya ocurrido ahora en el working tree.
git status [<options>...] [--] [<pathspec>...]
Muestra las rutas que tengan cambios entr el index y el HEAD, rutas que tengan cambios entre el working tree y el index, y rutas en el working tree que no están siendo seguidas por git y tampoco siendo ignoradas por gitignore.
git checkout
Actualiza los ficheros del working tree para que coincidan con la versión del index o del árbol especificado. Típicamente, git checkout actualizará HEAD para poner la rama especificada como rama actual. Tip: Utilizar git checkout -b <rama> crea una rama nueva y la especifica como rama actual. Es equivalente a hacer git branch <rama> && git checkout <rama>
git branch
Lista, crea y borra ramas.
Sin argumentos, lista las ramas del repositorio, siendo la actual la que tiene un asterisco.
Especificando un nombre de rama (que no exista) creará la rama pero no la pondrá como rama actual. Para ello hay que utilizar git checkout.
-m y -M sirven para modificar el nombre de una rama, y -d para borrarla (si ha sido integrada completamente en la rama de la que se creó, o si no hay rama upstream).
-D permite borrar una rama que no haya sido integrada (úsese con precaución!)

Comandos básicos, más o menos ya están. Ahora faltan aquellos que permiten interactuar con SVN.
Si ya habeis utilizado Git en un pasado, no podreis utilizar git push y git pull, pues estos trabajan con repositorios Git, y no está recomendado pasar datos entre repositorios git descentralizadamente, según el manual. El modo recomendado de trabajar es o bien enviar los cambios al svn centralizado o bien utilizando git format-patch y git am.

Comandos para la integración con svn

git svn init [--stdlayout] [--trunk=<trunk_subdir>] [--tags=<tags_subdir>] [--branches=<branches-subdir>] <svn-repo>
Inicializa un repositorio Git a partir de un svn remoto. –stdlayout indica que el repositorio está estructurado con la estructura típica (branches/, tags/, trunk/). Se pueden especificar varias –branches y git las seguirá a todas.
git svn fetch [--localtime] [--parent]
Se baja revisiones nuevas del Subversion remoto que estemos siguiendo.
–localtime guarda los tiempos de los commits de Git en la timezone local en lugar de UTC. Esto hace que git log muestre las mismas fechas que haría svn log para la timezone actual. Esto no interfiere con el repositorio del que has clonado, pero si quieres que tu repositorio pueda interactuar con otro repositorio Git, no deberías utilizar esta opción, o estar ambos en la misma timezone.
git svn rebase
Esto coge revisiones contra el SVN que corresponda con el HEAD actual y hace rebase sobre el contenido del trabajo actual (que aún no se haya subido al SVN) contra las revisiones nuevas.

Esto funciona como svn update o como git pull, si ya has usado git, a excepción de que preserva el historial lineal con git rebase en lugar de git merge para que sea más fácil hacer dcommit con git svn.
al igual que git rebase esto requirere que el working tree esté limpio y no haya cambios sin subir
git svn dcommit
Envía cada cambio directamente al repositorio SVN, y luego hace rebase o reset (según haya un diff entre SVN y la cabeza o no). Esto crea efectivamente una revisión en SVN por cada commit en git. Se puede especificar una revisión o rama, y esto hará que se realice el trabajo como si la cabeza fuese el argumento especificado, en lugar de HEAD.
git reset -r <n> || –revision=<n> [-p | --parent]
Deshace los efectos de fetch hasta la revisión que se especifique. Esto permite volver a hacer fetch de una revisión SVN. Generalmente los contenidos de una revisión de SVN no cambian jamás, y reset no debería ser necesario. Pero si por alguna razón es necesario reparar tu repositorio, el único modo es usar reset.

Todavía tengo que probarlo en profundidad, pero la forma de trabajar debería de ser algo así:

mkdir proyecto
cd proyecto && git svn init https://svn.fic.udc.es/… –stdlayout # tenemos una estructura tags/, branches/, trunk/
git svn fetch –all # cogemos todas las versiones para que git las conozca
git svn rebase # ponemos ‘master’ a la última revisión del svn

git checkout -b mitrabajo # creamos una rama distinta para trabajar en ella
### Trabajamos…
# hacemos incluso algún git commit en la rama mitrabajo para ir versionando cosas…

git checkout master # volvemos a la rama ‘master’ (que por defecto contiene el trunk/)
git svn rebase # comprobamos que no haya más cambios
# mezclamos los nuestros en master

git merge –ff-only –squash mitrabajo # squash mezcla todo el trabajo que hayamos hecho en un único commit
git commit # actualizamos nuestro ‘master’
git svn dcommit # subir los cambios de master al svn

#opcionalmente,
# o bien:

git branch -d mitrabajo # borramos la rama
# o bien la actualizamos con lo que tiene master
git checkout mitrabajo && git merge master
# o bien le hacemos rebase, así
git checkout mitrabajo
git reset –hard master # reseteamos la rama mitrabajo al último commit que hay en master

# Actualizamos el Trac del proyecto
bash sync.sh

Día de la Ciencia en la Calle: Mañana.

Sábado, mayo 8th, 2010

Mañana es el día de la Ciencia en la Calle.
Una iniciativa de la alianza de museos de A Coruña que realiza una exposición anual, que cae en el primer sábado después del primer viernes del mes de mayo. Es decir, mañana.

Es un evento en el que facultades e institutos tratan de acercar la ciencia al público general, mediante ejemplos que tratan de ser lo más claros e ilustrativos que pueden sobre algún tema científico o tecnológico.

Nosotros aquí, desde la Facultad de Informática de A Coruña (FIC) vamos a llevar varios proyectos entre los que está muy presente el software libre.

Entre ellos, un coche teledirigido, un proyecto de interfaces modernas (una mesa táctil), realidad aumentada, un stand de software libre, ‘temas’ sobre wifi y seguridad informática (incluyendo probablemente un ataque man-in-the-middle en directo), y una casa domótica.

Más tarde se dará información más particular sobre esto. Que es el día antes y no hay que adelantar acontecimientos.
Así que si no quereis perdéroslo y verlo en primicia, os invito a venir al Parque de Santa Margarita (alrededores de la Casa de las Ciencias) mañana, a cualquier hora del día.

Actualización: Estoy demasiado dormido para escribir sobre este día, así que os remito al blog de Linealibre para mayor información al respecto. Hemos estado programando toda la noche.

Ejercicio 2: Examen de Matemática Discreta

Martes, febrero 9th, 2010

Enunciado

Sean { x e y } dos personas, y la proposición p(x, y) “x puede mentir a y”.
Enuncia, tanto en lenguaje formal como en lenguaje natural, la proposición contraria a “∃x ∀y p(x, y)”
Nota: No puede haber una negación antes de un cuantificador, y la frase no puede empezar por construcciones del tipo “No es cierto que…”.

En lenguaje natural, ∃x ∀y p(x, y) se lee «Existe alguien que es capaz de mentir a todo el mundo».

Buscamos ¬ [ ∃x, ∀y, p(x, y) ] <=> ∀x ¬[ ∀y, p(x, y) ] <=> ∀x ∃y ¬p(x, y).
La lectura, en lenguaje natural, de esto último, es:
«Todo el mundo tiene alguien a quien no puede mentir».