03/07/2014

Mon chti blog >> Fossil, ssh et nanojail

Tags:
fossil
sjail
sshd

Aimant avoir le contrôle de mes développements, je n'ai pas succombé aux sirènes des forges et préfère utiliser fossil.

Ce système de contrôle de version fournit, au sein d'un unique binaire, tout ce qu'on peut attendre de ce type d'outil et réussit le tour de force d'intéger un wiki et un gestionnaire de ticket.

Voyons comment mettre en place ce service à partir des ingrédients suivant:

Fixons les objectifs:

Commençons par créer une jail à l'aide de sjail:

$ cd $HOME && mkdir -p tmp/sjail && fetch -o sjail.tar.gz 'http://fossil.bsdsx.fr/sjail/tarball/sjail.tar.gz?uuid=trunk'
$ alias sjail $HOME/tmp/sjail/sjail
$ cd $HOME && mkdir -p tmp/fossil && cd tmp && sjail fossil init
If you need log, don't forget to add '-l /usr/home/dsx/tmp/fossil/var/run/logpriv'
on syslogd_flags and restart (not reload) syslogd
You could edit /usr/home/dsx/tmp/fossil/usr/local/etc/pkg/repos/sjail.conf before adding any package to match your configuration

Avant d'ajouter /usr/sbin/sshd les plus curieux iront regarder $HOME/tmp/sjail/_sjail_usr_sbin_sshd:

$ sjail fossil /usr/sbin/sshd

Un soupçon de configuration (à adapter suivant vos goûts):

$ cat >> fossil/etc/ssh/sshd_config
UseDNS no
UsePAM no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
StrictModes no
AuthorizedKeysFile /etc/ssh/authorized_keys
AllowGroups src
^D

Pour faire court: j'interdis un maximum de chose et je centralise les clefs des utilisateurs. De toute façon, leur $HOME sera en lecture seule, aucune raison qu'ils y déposent quoi que ce soit.

ATTENTION à StrictModes ! L'arborescence générale de mes jails n'est pas créée par root et cela peut poser problème avec sshd. Sans cette directive, fossil/etc/ssh doit appartenir à root ce qui n'est pas le cas chez moi. Ce n'est pas une faille de sécurité mais un contrôle supplémentaire. L'objectif est de pouvoir manipuler le fichier des clefs depuis l'hôte.

Je rajoute à cette jail /usr/sbin/daemon afin que fossil tourne en temps qu'utilisateur non privilégié:

$ sjail fossil /usr/sbin/daemon
$ sjail fossil pkg install fossil

Passons à la configuration desdits utilisateurs:

$ cat >> fossil/etc/pw.conf
defaultpasswd no
home /repos
homemode 500
shells sh
defaultshell sh
defaultgroup src
minuid 30000
maxuid 31000
^D

Il est temps de créer ce fameux groupe src:

$ sudo chroot fossil pw groupadd src -g 30000

Et un utilisateur toto:

$ sudo chroot fossil pw useradd toto -c 'toto commiter' -m
Password for 'toto' is: 3bzM/cNT
$ grep ^toto fossil/etc/passwd
toto:*:30000:30000:toto commiter:/home/toto:/bin/sh
$ ls -la fossil/home/
total 12
drwxr-xr-x  3 root   wheel  512 Jul  1 22:03 .
drwxr-xr-x  6 dsx    wheel  512 Jul  1 22:00 ..
dr-x------  2 30001  30000  512 Jul  1 22:03 toto

Le service fossil sera exécuté (froidement) par l'utilisateur nobody, je crée le répertoire /repos avec les droits kivonbien:

$ mkdir fossil/repos && sudo chown -R nobody:30000 fossil/repos && sudo chmod -R 775 fossil/repos

La configuration de la jail (attention à la configuration réseau à adapter):

$ cat /etc/jail.conf
exec.clean;
mount.devfs;
exec.jail_user = "root";
exec.consolelog = "/var/log/jails/$name";
fossil {
        path = "/home/dsx/tmp/fossil";
        host.hostname = "fossil.bsdsx.fr";
        ip4.addr = lo1|10.30.12.2;
        exec.start = "/usr/sbin/sshd -e";
        exec.start += "/usr/sbin/daemon -c -u nobody /usr/local/bin/fossil server --files *.json,*.html,*.js,*.css,*.txt --notfound /index.html /repos";
}
$ sudo jail -c fossil
fossil: created

Il me faut une clef pour mon utilisateur toto afin de tester l'accès par ssh:

$ ssh-keygen -q -t rsa -N "" -C "toto's rsa key" -f toto
$ cat toto.pub >> fossil/etc/ssh/authorized_keys
$ ssh -F /dev/null toto@10.30.12.2 -i toto
The authenticity of host '10.30.12.2 (10.30.12.2)' can't be established.
RSA key fingerprint is 2f:e7:02:1c:cc:65:00:06:1b:4d:75:6c:f0:11:e8:cf.
No matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.30.12.2' (RSA) to the list of known hosts.
$ echo /*bin/*  /usr/*bin/* /usr/local/*bin/*
/bin/sh /sbin/ldconfig /usr/sbin/daemon /usr/sbin/nologin /usr/sbin/pw /usr/sbin/pwd_mkdb /usr/sbin/sshd /usr/local/bin/fossil
$ ls
ls: not found
$ echo pouet > toto
cannot create toto: Permission denied

Fervent adepte de chroot, je pensais pouvoir utiliser la commande suivante pour créer un premier projet:

$ sudo chroot -u nobody fossil /usr/local/bin/fossil init /repos/systemd.fossil
invalid home directory: /root

Après avoir essayer:

J'en suis arrivé à la conclusion suivante: on ferait mieux de commencer par le commencement.

$ sudo chroot -u nobody fossil/ /bin/sh 
$ echo $HOME
/root

Tout s'explique. Je disais donc, initialisons un projet de domination du monde:

$ sudo chroot -u nobody fossil /bin/sh -c 'HOME=/repos; /usr/local/bin/fossil init /repos/systemd.fossil'
project-id: 7e8592bc69fbccb40162ef6a17235b8945ed6225
server-id:  c59ad0fe02d3f67d11d2406a951d53602d4cd027
admin-user: root (initial password is "1abd87")

C'est pas encore ça. Mêmes maux, mêmes remèdes:

$ sudo chroot -u nobody fossil /bin/sh -c 'HOME=/repos; USER=nobody; /usr/local/bin/fossil init /repos/systemd.fossil'
project-id: a8581c262d2925e760718319cf5e65287afe60d0
server-id:  22dca47163f6911ba39aba051643418e11364db0
admin-user: nobody (initial password is "4ae1c5")

Est-ce que notre utilisateur toto peut commiter ?

$ cat ~/.ssh/config
Host fossil
    User toto
    IdentityFile ~/.ssh/toto
    IdentitiesOnly yes
$ cd && mkdir -p src/toto && cd src/toto && mkdir src fossils
$ fossil clone ssh://fossil//repos/systemd.fossil fossils/systemd.fossil

ATTENTION !!! Le double / devant repos n'est pas une typo !

Round-trips: 2   Artifacts sent: 0  received: 3
Clone finished with 543 bytes sent, 1044 bytes received
Rebuilding repository meta-data...
  100.0% complete...
project-id: a8581c262d2925e760718319cf5e65287afe60d0
admin-user: dsx (password is "077a9a")
$ cd src/
$ fossil open ../fossils/systemd.fossil 
project-name: <unnamed>
repository:   /usr/home/dsx/src/toto/src/../fossils/systemd.fossil
local-root:   /usr/home/dsx/src/toto/src/
config-db:    /home/dsx/.fossil
project-code: a8581c262d2925e760718319cf5e65287afe60d0
checkout:     8c1b91007ea057d7e9d1a7fbddde1f88b7c4ef45 2014-07-03 19:05:16 UTC
leaf:         open
tags:         trunk
comment:      initial empty check-in (user: nobody)
checkins:     1
$ touch neuneu && fossil add neuneu && fossil commit -m 'add neuneu' neuneu
ADDED  neuneu
Autosync:  ssh://fossil//repos/systemd.fossil
Round-trips: 1   Artifacts sent: 0  received: 0
Pull finished with 319 bytes sent, 228 bytes received
New_Version: 4fcf2e727ba9e86eb64d5dc9ea1c967a7fe9ff59
Autosync:  ssh://fossil//repos/systemd.fossil
Round-trips: 1   Artifacts sent: 2  received: 0
Sync finished with 518 bytes sent, 282 bytes received

Cerise(s) sur le gâteau

Qui dit ssh pense aussitôt FORCE_COMMAND

$ cat fossil/etc/ssh/authorized_keys
command="/usr/local/bin/fossil http /repos/systemd.fossil" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCsZv7o9FjGBW8hpLcCuqE2EC8Togg01M7b5B7k2ogYz+ZnntIwiQcRy9MEUMfY7rK0fhnKiJNd7lg1jUwoZMjbkIOuc/AKe8V3HLALDY/1609IzAb243sVgRGEG6Ezfi2l/PT6Ej2mldwx99L7plXgIZwA5JEdjiaz2SczxtZDAJoBJm1R/lmBc7Min0shV4hzXRcUZ0ncPs84OAfd8hiKbbSOSvhLyqebBmHpUHRiMX6AZkQaUv/JHxl/gPoL996DAPdWso1G0vpniYWw/EFqGVb0D+8omnccpJ/q0hXF/SsuZbeaTcNZX1H8DRgL5+7Bs/ZHZb1Kuhj3iucs8kV toto's rsa key
$ fossil clone ssh://fossil//repos/systemd.fossil fossils/systemd.fossil
Round-trips: 2   Artifacts sent: 0  received: 3
Clone finished with 543 bytes sent, 1045 bytes received
Rebuilding repository meta-data...
  100.0% complete...
project-id: 816a46cf938e770be7dde7323969efdb6e13eb70
admin-user: dsx (password is "cbfaa5")
$ ssh fossil
^CConnection to fossil.bsdsx.fr closed.

Avantages:

Est-ce qu'on peut encore faire mieux ? Je pense que oui:

Ombre(s) sur le gâteau

fossil est lancé en tant qu'utilisateur nobody, il ne peut donc pas écouter sur un port inférieur à 1024 (ce qui tombe bien car par défaut il écoute sur 8080). Mais comment accéder à l'interface web ? La raréfaction des adresses ipv4 impose bien souvent l'utilisation d'un reverse proxy tel que nginx. Pour l'ipv6, il faudra jouer de la redirection de port (80 -> 8080).

Retours

Remarque pertinente (comme à son habitude :) de Natacha: définir le HOME des utilisateurs à /repos. Premier effet kisskool:

$ fossil clone ssh://fossil//repos/systemd.fossil fossils/systemd.fossil
# devient
$ fossil clone ssh://fossil/systemd.fossil fossils/systemd.fossil

Deuxième effet kisskool: inutile de créer des répertoires pour les utilisateurs:

$ sudo chroot fossil pw useradd toto -c 'toto commiter' -m
# devient
$ sudo chroot fossil pw useradd toto -c 'toto commiter'

et

$ cat >> fossil/etc/pw.conf
defaultpasswd random
home /home
homemode 500
shells sh
defaultshell sh
defaultgroup src
minuid 30000
maxuid 31000
^D
# devient
$ cat >> fossil/etc/pw.conf
defaultpasswd random
home /repos
shells sh
defaultshell sh
defaultgroup src
minuid 30000
maxuid 31000
^D

Contre effet kisskool: le $HOME des utilisateurs devient accessible en écriture mais contre contre effet kisskool avec la commande forcée par la clef.

Merci Natacha !

Retour bis

Les perfectionnistes pourront:


02/07/2014

Emile "iMil" Heitor 's home >> Back to 2000-2005: FreeBSD desktop

Par : iMil
Tags:
Blogroll
Desktop
FreeBSD
NetBSD

A while ago, I had my ${DAYWORK} workstation running NetBSD, and honestly, it did pretty well. Things began to become more painful when there was no more DRI acceleration with the radeon driver, it then did an okay-ish job, but the overall desktop became somewhat laggy.
It was told someone was working on porting KMS/GEM, that was more than a year ago, and as of today, that work -and I guess it is not an easy one- isn’t mature enough to be used as a workstation, I need my desktop to run various tools, and not only terminal-based ones.
Two weeks ago, I asked for a new desktop, more powerful, so I can run more virtual machines with it. That new box was shipped with an nvidia graphic card and various modern components which I knew were not supported by NetBSD. This is one regret I have about that beautiful project, running on VAX, PlayStation 2 and Amiga is fun, but I’ll tell you a little secret: nobody cares anymore about VAX, PlayStation 2 and Amiga.
So I gave FreeBSD 10 a try. And I was not disappointed: everything, and I mean everything worked almost out-of-the-box. Of course there was a bit of fighting with the proprietary nvidia driver, but it worked as expected with 3D acceleration and all.
Not everything is perfect either, but I must say FreeBSD does a great job as a workstation, actually, it does what I needed: display a decent 2014 hardware powered desktop, no more, no less.
Under no circumstances will I replace my NetBSD servers / virtual machines (as long as they still support the underlying hardware!), they do an amazing job and I am quite happy with them, but don’t expect desktop-related commits from me to pkgsrc for the time being…

Update

Well well, this blogpost have bring much unexpected rage. Just to clarify: this is definitely not a troll or whatsoever, only an end user opinion on what’s preventing me of using NetBSD as a desktop at work for the moment.
Read the previous sentence a couple of times and notice the word “work”, the place where you can’t spend countless hours patching / tuning / trying / crashing / rebooting (sounds like a Daft Punk song) before you can reply to an urgent customer inquiry. Yes, that place. The only thing I say is: FreeBSD, as of today, does a better job at being an out-of-the-box modern desktop.
I will continue to use NetBSD as my server OS of choice, because it does rock, because it is stable, simple and fills the task perfectly. As soon as it doesn’t anymore, I’ll switch to something else, that’s what I do. Pragmatic.
So yes, I have the weakness to like shiny desktops that run something else than twm, I like transparency, I like effects when I change my virtual desktop, I like my windows to be displayed and moved rapidly, you know, pretty much like all those BSD developers that actually use OSX because it does all those things.
I will also continue contributing to pkgsrc, because it is in my optinion the most beautifull packaging system around, all I’m saying is that I won’t commit desktop-related tools I can’t really test or use. Nothing more.

The post Back to 2000-2005: FreeBSD desktop appeared first on Emile "iMil" Heitor 's home.


01/07/2014

Emile "iMil" Heitor 's home >> Back to 2000-2005: FreeBSD desktop

Par : iMil
Tags:
Blogroll
Desktop
FreeBSD
NetBSD

A while ago, I had my ${DAYWORK} workstation running NetBSD, and honestly, it did pretty well. Things began to become more painful when there was no more DRI acceleration with the radeon driver, it then did an okay-ish job, but the overall desktop became somewhat laggy.
It was told someone was working on porting KMS/GEM, that was more than a year ago, and as of today, that work -and I guess it is not an easy one- isn’t mature enough to be used as a workstation, I need my desktop to run various tools, and not only terminal-based ones.
Two weeks ago, I asked for a new desktop, more powerful, so I can run more virtual machines with it. That new box was shipped with an nvidia graphic card and various modern components which I knew were not supported by NetBSD. This is one regret I have about that beautiful project, running on VAX, PlayStation 2 and Amiga is fun, but I’ll tell you a little secret: nobody cares anymore about VAX, PlayStation 2 and Amiga.
So I gave FreeBSD 10 a try. And I was not disappointed: everything, and I mean everything worked almost out-of-the-box. Of course there was a bit of fighting with the proprietary nvidia driver, but it worked as expected with 3D acceleration and all.
Not everything is perfect either, but I must say FreeBSD does a great job as a workstation, actually, it does what I needed: display a descent 2014 hardware powered desktop, no more, no less.
Under no circumstances will I replace my NetBSD servers / virtual machines (as long as they still support the underlying hardware!), they do an amazing job and I am quite happy with them, but don’t expect desktop-related commits from me to pkgsrc for the time being…

The post Back to 2000-2005: FreeBSD desktop appeared first on Emile "iMil" Heitor 's home.


26/06/2014

Weblog de Natacha >> Devinette ratée

Par : Natacha Kerensikova
Tags:
Tarée

Ça fait deux fois en moins d'une semaine que je me retrouve à un évènement social dans lequel on en vient à échanger des devinettes mathématiques, et dans lequel je propose : « On prend une boule, on la découpe en cinq morceaux, et on les réarrange pour former deux boules, chacune identique à la boule de départ. »

Et à chaque fois, c'est tombé à plat. Alors que c'est pourtant facile et archi-connu. Je ne comprends pas.


25/06/2014

Bapt >> fossil in prison

Par : Bapt
Tags:
FreeBSD
fossil
jails
scm

Since my last post about how I do host fossil I have been asked write about the new setup I do have

The jail content

I have created a minimal jail:

$ find /usr/local/jails/fossil -print
/usr/local/jails/fossil/var
/usr/local/jails/fossil/var/tmp
/usr/local/jails/fossil/libexec
/usr/local/jails/fossil/libexec/ld-elf.so.1
/usr/local/jails/fossil/bin
/usr/local/jails/fossil/bin/sh
/usr/local/jails/fossil/bin/fossil
/usr/local/jails/fossil/lib
/usr/local/jails/fossil/lib/libc.so.7
/usr/local/jails/fossil/lib/libssl.so.7
/usr/local/jails/fossil/lib/libreadline.so.8
/usr/local/jails/fossil/lib/libz.so.6
/usr/local/jails/fossil/lib/libcrypto.so.7
/usr/local/jails/fossil/lib/libncurses.so.8
/usr/local/jails/fossil/lib/libedit.so.7
/usr/local/jails/fossil/data
/usr/local/jails/fossil/dev

/bin/sh is necessary to get the exec.start jail argument to work /var/tmp is necessary to get fossil to open his temporary files (I created it with 1777 credential) /data is a empty directory where the fossil files will be stored

Jail configuration

The configuration file is the following:

fossil {
	path = "/usr/local/jails/fossil";
	host.hostname = "fossil.etoilebsd.net";
	mount.devfs;
	ip4.addr="127.0.0.1";
	exec.start = "/bin/fossil server -P 8084 --localhost --files *.json,*.html,*.js,*.css,*.txt --notfound /index.html /data &";
	exec.system_jail_user = "true";
	exec.jail_user = "www";
	exec.consolelog = "/var/log/jails/fossil.log" ;
}

More about fossil itself

In /data I created an index.html which is an almost empty html with a bit of Javascript.

When loading the javascript will request a list.txt file.

This file contain the list of repositories I want to show publically (one per line).

For each of them the javascript will use the json interface of fossil (meaning your fossil has to be built with json) and gather the name and the description of the repo to print them on the index.

Starting/Stopping the service

2 simple command are necessary to manage the service:

Starting up:

# jail -c fossil

Stopping:

# jail -r fossil

The service is only listening on the localhost, it is up to you to create your reverse proxy, in my case I do use nginx with the following config:

server {
	server_name fossil.etoilebsd.net;
	listen       [::]:443 ssl;
	listen       443 ssl;
	ssl_certificate     ssl/fossil.crt;
	ssl_certificate_key ssl/fossil.key;

	location / {
		client_max_body_size 10M;
		proxy_buffering off;
		proxy_pass http://127.0.0.1:8084/;
		proxy_set_header HTTPS on;
		proxy_set_header   Host             $host;
		proxy_set_header   X-Real-IP        $remote_addr;
		proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
	}
}

16/06/2014

code. grind. sleep. >> pgbench et .pgpass

Tags:

En faisant quelques tests sur le Foreign Data Wrapper, j'ai (re)fait un peu de pgbench. Pour ceux qui ne savent pas pgbench permet de simuler un benchmark TPC-B, en gros des lectures, des écritures par un certain nombre de sessions concurrentes.

Même si on peut le considérer simpliste par rapport à un Tsung, il est fourni dans les contribs de PostgreSQL et permet de facilement tester un aspect qu'on néglige souvent : les effets de la concurrence sur une base.

J'ai donc monté mon petit environnement de test avec un rôle pour pgbench et sa base dédiée. Pour aller plus vite, j'en ai profité pour configurer un fichier .pgpass, sauf que pgbench n'en voulait pas :

postgres@fdw:~$ cat .pgpass 
localhost:5432:*:bench:Clair!

postgres@fdw:~$ pgbench -h localhost -n -c 10 -j 10 -U bench bench
Password: 
Connection to database "bench" failed:
fe_sendauth: no password supplied

Poutant, la ligne pour l'utilisateur bench est correcte. Si on lui fournit explicitement le port 5432, il tient compte de l'entrée dans le .pgpass :

postgres@fdw:~$ pgbench -h localhost -n -c 10 -j 10 -U bench -p 5432 bench
transaction type: TPC-B (sort of)
scaling factor: 500
query mode: simple
number of clients: 10
number of threads: 10
number of transactions per client: 10
number of transactions actually processed: 100/100
tps = 77.993447 (including connections establishing)
tps = 88.977249 (excluding connections establishing)

La lecture de ce thread, qui se conclut sur ce patch, nous éclaire sur ce comportement.

Selon le message de commit, la modification change le comportement de la libpq. Elle n'a pas été backportée sur les autres branches et ne sera donc disponible que pour la libpq de la version 9.4 (ou Debian/Ubuntu qui prend toujours la dernière version de la libpq).


29/05/2014

Philpep's blog >> Faire un code compatible python 2 et 3

Par : Philippe Pepiot
Tags:
python

Je suis un développeur python et j'écris principalement du code compatible python 2.7 et parfois 2.6. Seulement, python 3 est sorti depuis longtemps, avec des fonctionnalités bien sûr, mais surtout chaque nouvelle release montre une volonté de rendre la migration plus simple pour les développeurs, et il est maintenant tout à fait possible d'écrire du code qui soit compatible python 2 et 3. Même si votre cible en production reste python 2, python 3 est bien l'avenir de python donc il est temps d'apprendre à faire du code compatible sur les deux releases majeures de votre langage préféré.

Au boulot, j'écris des drivers d'automate d'analyses médicales, ces machines sont souvent à la pointe de la technologie sauf sur la partie informatique où on trouve encore des ports série avec des protocoles de communication complètement farfelus. Le code fait 25k lignes d'après sloccount, il y a un coverage par les tests qui est supérieur à 80%. Mon objectif était de faire passer les tests sur python 3.

Avant de se lancer, il faut s'armer des meilleurs outils:

Premièrement on installe les interpréteurs avec pyenv, par exemple:

pyenv install -v 2.7.6
pyenv install -v 3.3.5
pyenv install -v 3.4.1

Ensuite on configure tox dans le fichier tox.ini:

[tox]
envlist = py27,py33,py34

[testenv]
deps=-rtest-requirements.txt
commands=nosetests

Et on lance les tests, le but du jeu va être de lancer les tests et de les corriger un par un.

Unicode

Une fonctionnalité majeure dans python 3 est la nouvelle gestion de l'unicode. Il y a maintenant une différence stricte entre le type bytes, qui est plus ou moins l'équivalent du type str en python 2, et le type str qui lui est l'équivalent du type unicode en python 2. En python 3 on ne peut plus combiner ces types sans explicitement décoder les bytes et encoder les chaines unicode.

python2.7 -c 'print(u"foo" + "bar")'
# et l'équivalent en python3:
python3.3 -c 'print("foo" + b"bar")'
Traceback (most recent call last):
    File "<string>", line 1, in <module>
TypeError: Can't convert 'bytes' object to str implicitly

Mon code était truffé de mélanges entre ces deux types, tout simplement parce qu'en python2 il y a une conversion implicite (Ce qui peut produire les déroutantes exceptions UnicodeEncodeError et UnicodeDecodeError si on ne fait pas attention).

La première chose à faire est de préfixer tous les bytes par un b, ce qui n'a aucun effet en python 2 mais qui est nécessaire en python 3.

# <stx>foo<etx>
b"\x02foo\x03"

Ensuite pour les chaines qui devraient être de l'unicode il y a deux solutions:

Il y a du pour et du contre dans tous les cas, personnellement j'ai opté pour unicode_litterals parce que ça fait un code moins lourd et plus proche de python 3. Tout dépend du code à migrer et de votre capacité à le modifier, il y a un bon article qui détaille les arguments.

Les bytes

Les bytes en python 3 ne se comportent pas exactement comme les bytes en python 2.

# python 2
>>> b"\x06"[0]
"\x06"
>>> b"\x06"[0] == "\x06"
True
>>> b"\x06"[:1] == "\x06"
True

# python 3
>>> b"\x06"[0]
6
>>> b"\x06"[0] == b"\x06"
False
>>> b"\x06"[:1] == b"\x06"
True

Pour faire du code compatible, j'ai utilisé des slices ou la fonction six.byte2int().

De la même manière j'avais des implémentations de checksum qui nécessitaient d'itérer sur la valeur numérique des bytes que j'ai modifié en utilisant six.iterbytes():

# python 2
checksum = (sum(ord(c) for c in data) & 0xFF) % 0x100

# python 3
checksum = (sum(c for c in data) & 0xFF) % 0x100

# python 2 et 3
checksum = (sum(c for c in six.iterbytes(data)) & 0xFF) % 0x100

Les bytes de python 3 ne supportent pas les formats, ni avec % ni avec la fonction format(). Avec la pep461 elles vont revenir dans python 3.5, mais en attendant on peut faire des concaténations et passer par des chaines unicode pour le formatage.

STX = b"\x02"
ETX = b"\x03"
# code python2
data = b"%s%s%02X%s" % (STX, payload, checksum, ETX)

# code python 2 et 3
data = STX + payload + ("%02X" % checksum).encode("ascii") + ETX

Metaclass

Rien de bien compliqué ici:

# python 2
class Foo(object):
    __metaclass__ = MetaFoo
    pass

# python 3
class Foo(metaclass=MetaFoo):
    pass

# python 2 et 3
@six.add_metaclass(MetaFoo)
class Foo(object):
    pass

Le reste

Les méthodes items(), keys() et values() des dictionnaires en python 3 sont les mêmes que iteritems(), iterkeys() et itervalues() en python 2.

# python 2
d.iteritems()

# python 3
d.items()

# python 2 et 3
six.iteritems(d)

Et de la même manière:

# python 2
d.items()

# python 2 et 3
list(d.items())

Pour le reste, je vous conseille la lecture de la documentation du module six. Moi je m'en suis beaucoup servi pour six.string_types à la place de basestring et les imports (Queue, StringIO, ...)

Conclusion

Maintenant le code est plus beau, il fonctionne sur python 3, de nombreux potentiels bugs ont été corrigés grâce à python 3 qui est plus strict sur les types, et tout ça ne m'a pris que quelques heures.


28/05/2014

code. grind. sleep. >> Migration du blog sur github

Tags:

Finalement le temps ne me permettant plus d'administrer mon serveur dédié comme il faut, j'ai décidé de l'abondonner et transférer mes services ailleurs. Pour le blog et le wiki, j'ai choisi de faire un site/blog github avec jekyll, vu que c'est tout prémaché.

Sur github, l'hébergement c'est du fichier html, donc statique, on a plusieurs possibilités pour créer un site :

L'avantage de pelican est dans sa capacité à importer le contenu d'un blog dotclear, et transformer la syntaxe en markdown. Le markdown semble avoir la cote, beaucoup de générateurs de site l'utilisent, d'ailleurs je m'y suis mis.

Comme j'avais déjà fait le site de pitrery avec jekyll sur github, la migration fut plus facile, une fois le dotclear migré grâce à pelican.

Au final, j'ai maintenant un truc tout simple avec un thème bootstrap, et le jekyll de base de github est largement suffisant.

La bonne découverte fut pandoc, un super convertisseur de format de document texte, qui va me servir pour la migration du dokuwiki à base de :

pandoc -f html -t markdown http://wiki.orgrim.net/page?do=export_html

Le mot de la fin, ça demande un peu de boulot de nettoyage manuel, mais vu le nombre impressionant de posts que j'ai pu produire en quatre ans, c'était pas trop méchant.


27/05/2014

Weblog de Natacha >> Mon nouveau clavier, il est topr bien

Par : Natacha Kerensikova
Tags:
Jouets

Clavier Realforce 87U

Mille mercis à Popov qui m'a permis d'essayer cette merveille et qui du coup m'a convaincue de m'acheter le même.


26/05/2014

Weblog de Natacha >> Garmin eTrex 20

Par : Natacha Kerensikova
Tags:
Jouets

Il y a très longtemps, dans une galaxie lointaine, j'ai ressenti un sérieux besoin de GPS de piéton, au point de lancer un appel à l'aide pour en choisir un.

Dans les commentaires ce billet, j'ai échangé avec ChrisJ autour de son expérience avec l'Oregon 300. Parallèlement j'ai regardé autour de la gamme eTrex de Garmin, que j'ai découvert par le témoignage de David Madore.

J'ai un peu exploré les autres gammes et les autres marques de GPS, mais sans rien trouver d'aussi convainquant. Je ne suis pas complètement sûre d'avoir vraiment donné autant de chances aux autres qu'à Garmin, j'ai peut-être été biaisée par l'effet de simple exposition.

Bref, le dilemme s'est finalement réduit à eTrex contre Oregon ou Dakota, autrement dit à écran tactile ou non.

Comme le titre du présent billet le spoile, j'ai finalement succombé pour l'eTrex 20 :

Garmin eTrex 20

Depuis, j'ai fait avec les RMLL 2013 à Bruxelles, le FOSDEM 2014 au même endroit, moult chemins à pied dans Paris et dans sa banlieue, et un peu d'assistance au GPS de la voiture, aussi bien aux alentours de Bruxelles qu'en région parisienne, et peut-être aussi dans la campagne profonde où vivent mes parents (je ne suis plus sûre de l'avoir sorti pendant ce séjour).

Ce billet est donc en quelque sorte un « un an avec un eTrex 20 », mais j'ai renoncé à ce titre parce que la pertinence de l'année me semble douteuse, vu qu'il a passé l'immense majorité de ladite année au fond de sac à main, éteint.

Par contre, pendant les périodes où il n'était pas éteint, il m'a pleinement donné satisfaction.

Commençons par les critères a priori de mon cahier des charges :

Les considérations suivantes étaient au niveau de l'interface utilisateur, avec notamment le grand dilemme sur l'écran tactile.

En règle générale, je n'aime pas les écrans tactiles (ni les souris, d'ailleurs), donc j'ai opté pour un eTrex avec son interface à base de mini‐joystick et et de boutons.

À l'usage, je ne regrette pas ce choix. Certes, l'entrée de texte ou de nombre est très pénible, avec le joystick pour naviguer dans la sélection d'une touche dans un clavier virtuel, et ce serait mieux avec un écran tactile. Mais en contrepartie, je n'ai pas besoin de verrouiller l'appareil, et je peux l'attraper n'importe comment quand le besoin s'en fait sentir. Au total le bilan à mes yeux est positif.

Par contre au niveau de l'interface elle-même, je suis dans l'ensemble plutôt déçue. Je trouve que ça manque d'ingénieur UX chez Garmin.

Le plus gros point noir que j'ai trouvé à l'interface est la recherche de point à partir d'une adresse : il faut saisir un préfixe de la voirie, alors qu'une sous‐chaîne aurait été colossalement plus confortable (surtout à coups de joystick et avec mon esprit qui imagine facilement des sous‐chaînes pertinentes). Et quand par hasard l'adresse n'est pas notée comme dans la carte, par exemple une rue au lieu d'une avenue, ou un bd au lieu d'un boulevard…

Accessoirement, les seuls plantages du firmware que j'ai constatés étaient juste après la saisie d'un nom de ville ou de voirie.

Sinon il y a plein de petits trucs pas pratiques :

C'est là que l'on se rend compte de la puissance de l'Open Source : j'aurais eu accès au code de ce firmware et aux moyens nécessaires pour le recompiler, j'aurais probablement mis mon nez dedans pour essayer d'arranger ça. Et je doute que je serais la seule.

Enfin, pour finir sur une bonne impression, j'ajouterai que je suis très contente de la vitesse d'acquisition des satellite : souvent moins d'une minute. Mon seul point de référence est le GPS de la voiture, qui est certes nettement plus ancien, mais qui est beaucoup plus lent, au point d'utiliser mon eTrex 20 au début des trajets, en attenant que le GPS vocal puisse prendre le relai.

Bref, un (plus-si-)nouveau jouet dont je suis très contente et qui me semble bien mériter sa place au fond de mon sac à main.