Tensin

Aller au contenu Aller au menu Aller à la recherche

jeudi, mars 10 2011

Colorer différemment le background de vos sessions SSH

ShellPour mettre en couleur le fond d’un terminal sous Linux, il n’y a guère de solutions … Jusqu’ici le plus simple était de jouer avec les profils de Gnome-Terminal (ou autre) et d’associer à tous les onglets la même couleur de fond. Par contre pour avoir une couleur différente sur chaque onglet, c’était jusqu’ici mission impossible, ce qui au demeurant est relativement étonnant, pour ma part j’aurais besoin de cette fonctionnalité :

  • au travail pour avoir une couleur de fond différente selon le type de machine sur laquelle je me connecte (rouge pour les machines en production, noir pour les serveurs de développement par ex.) ;
  • chez moi pour différencier la machine sur laquelle je suis connecté (serveur domotique, serveur dédié en ligne, etc.) ;

Je configure bien ces infos dans le prompt (via PS1, avec le login et le hostname), mais c’est très insuffisant (pas suffisament visuel).

Or une solution plutôt élégante existe désormais, mise en place par Ian Blanes : un petit programme en C, sans dépendances, qui s’appelle “colorize”. C’est ce programme qui lance la commande ssh, redirige les entrées / sorties entre le terminal et la connexion ssh, et dans l’intervalle, modifie les couleurs de fond et/ou de police de caractères.

Colorize

Testée sous evilvte et gnome-terminal, çà fonctionne parfaitement bien, à priori sans ralentissements visibles. Ian explique toutefois que les lignes ayant déjà nativement un fond de couleur se comporteront mal (ce n’est quasiment jamais le cas chez moi).

Sources : http://deic.uab.es/~iblanes/colorize-0.1-src.tar.gz [Colorizer (sources) v0.1mirror ] Homepage : http://deic.uab.es/~iblanes/

L’installation est très simple :

wget http://deic.uab.es/~iblanes/colorize-0.1-src.tar.gz tar xzvf colorize-0.1-src.tar.gz make

Copier ensuite le programme colorize dans un répertoire accessible via le path, par ex. /usr/bin. Le lancement se fait ensuite via pour lancer un SSH avec un fond (-b) gris foncé (Ox333333) par ex. :

colorize -b 0x333333 — ssh root@192.168.0.1

Ensuite à l’utilisation, deux possibilités. Soit définir des alias de commande ssh pour chacune des machines sur laquelle se connecter.

alias ssh-production=’colorize -b 0x333333 — ssh root@192.168.0.1’

alias ssh-dedie=’colorize -b 0xCC0000 — ssh tensin’ # réutilisation alias défini dans ~/.ssh/config

Soit enrober l’appel de la commande ssh avec un fichier de paramétrie. Il suffit dans dans ce cas de créer un fichier ~/.ssh-colorize avec le contenu suivant (premier champ = le hostname, ou l’alias ssh ; deuxième champ, la couleur de background) :

192.168.0.2    0x440000
192.168.0.3    0x440000
solaris        0x000044

Et dans son fichier .profile (ou équivalent si autre shell) mettre en place la fonction suivante :

  1. function ssh {
  2. typeset DEST=$1
  3. if [[ -s ~/.ssh-colorize ]] ; then
  4. HOSTNAME=$(echo "$DEST" | sed 's/.*@//')
  5. egrep "^$HOSTNAME" .ssh-colorize 2>/dev/null | awk ' { print $2 } ' | read COLOR
  6. fi
  7. if [[ ! -z "${COLOR}" ]] ; then
  8. colorize -b "${COLOR}" -- /usr/bin/ssh "${DEST}"
  9. else
  10. /usr/bin/ssh "${DEST}"
  11. fi
  12. }

De fait, tous les appels ssh passeront par cette fonction, qui ira relire dans ~/.ssh-colorize, si renseigné, le code couleur de background à utiliser ! Ca permet de centraliser toutes les définitions de couleur de background et de facilement en ajouter sans devoir créer des alias.

mardi, mars 8 2011

Choix du workspace Eclipse à utiliser au démarrage via un launcher interactif (Linux)

EclipseComme je travaille avec plusieurs workspaces Eclipse (regroupant chaque plusieurs projets Eclipse corrélés entre eux, par ex. tous les modules d’un même projet, ou tous mes projets personnels Java ou PHP, ou tous mes projets de tests, etc.), il est beaucoup plus pratique pour moi de choisir le workspace sur lequel je veux travailler directement en démarrant Eclipse (plutôt que de switcher après coup).

De fait, tous mes raccourcis Eclipse pointent en fait sur le script ci-dessous.

Le script se base sur le méconnu mais assez pratique Zenity pour gérer la fenêtre de lancement, et se contente ensuite de démarrer Eclipse avec le paramètre -location chemin_du_workspace.

Visuellement et concrètement çà ressemble à çà, la liste des workspaces, le nombre de projets dans chaque workspace, il suffit de sélectionner celui sur lequel on veut démarrer :

workspaces-eclipse-launcher.png

Remarque : bien sûr l’autre manière de changer de workspace consiste à switcher depuis un Eclipse déjà démarré vers un autre workspace (ne pas oublier dans ce cas de cocher la petite case “Copy Settings > Workbench Layout” pour garder la disposition des fenêtres / perspectives).

workspaces-eclipse.png

Le script ( eclipse-launcher.sheclipse-launcher.sh ). A adapter pour les paramètres qui vous seraient propres, bien sûr (chemin vers Eclipse et paramètres additionnels Eclipse notamment).

  1. #!/bin/ksh
  2.  
  3. # ========================================================
  4. # === Variables
  5. # ========================================================
  6. export windows_title="Eclipse Launcher"
  7. export WNG_ICON="/opt/gnome/share/pixmaps/gnome-warning.png"
  8. export ECLIPSE_ICON="/opt/Eclipse_DEV/Eclipse-V3-2-1/icon.xpm"
  9. export WORKSPACES_DIR="/home/user/java/workspaces/eclipse/"
  10. export JAVA_HOME="/home/user/applications/java/jdk1.6.0_24"
  11. export ECLIPSE_BIN="/home/user/applications/eclipse/helios/java/eclipse"
  12. export JAVA_PARAMETERS="-vmargs -Xss4m -Xms326m -Xmx444m -XX:PermSize=256m -XX:MaxPermSize=256m"
  13.  
  14. # ========================================================
  15. # === Récupération de la liste des workspaces
  16. # === et construction pour affichage par Zenity
  17. # ========================================================
  18. WORKSPACES=""
  19. ls -1d "${WORKSPACES_DIR}"/* | egrep -v "\..*|*\.xml" | sort -u | while read ITEM
  20. do
  21. WORKSPACE_NAME="$(basename ${ITEM})"
  22. WORKSPACE_COUNT=$(ls -1d "${ITEM}"/* 2>/dev/null | grep -v total | wc -l)
  23. WORKSPACES="${WORKSPACES}${WORKSPACE_NAME} ${WORKSPACE_COUNT}
  24. "
  25. done
  26.  
  27. # ========================================================
  28. # === Lancement de Zenity
  29. # ========================================================
  30. ret=`zenity --list --width="320" --height="520" --window-icon="${ECLIPSE_ICON}" \
  31. --text "Choisissez le workspace" \
  32. --column "Workspace" \
  33. --column "Projets" \
  34. $WORKSPACES --title "${windows_title}"`
  35.  
  36. # ========================================================
  37. # === Démarrage d'Eclipse avec le bon workspace
  38. # ========================================================
  39. if [[ ! -z $ret ]] ; then
  40. export GTL_MODULES="";
  41. cmd='nohup '${ECLIPSE_BIN}' -showlocation -data "'${WORKSPACES_DIR}$ret'" -vm '${JAVA_HOME}'/bin/java ${JAVA_PARAMETERS} >/dev/null 2>&1 &'
  42. echo $cmd
  43. eval $cmd
  44. fi

Recevoir un mail de notification quand de nouveaux paquets apt-get sont disponibles

ShellAyant plusieurs machines dont deux connectées constamment sur le net’, je n’aime pas ne pas les avoir à jour. En même temps, je ne tiens pas à activer l’installation automatique des packages, afin de garder la main sur ce qui est installé et d’éviter les mauvaises surprises (typiquement pouvant survenir sur une montée de version sensible comme PHP).

Du coup j’ai installé ce petit script très simple en cron sur chaque machine, il tourne une fois par jour et m’envoi un mail pour m’indiquer s’il y a des mises à jour en attente sur ce système. Le principe est simplement de lancer la commande apt-get en mode simulation pour savoir s’il y a des installations à faire.

A noter :

  • j’utilise sur toutes mes machines le très simple esmtp plutôt que sendmail ;
  • le script fonctionne sur un système anglais ou français (j’ai les deux) ;
  • le script fonctionne sous Debian Squeeze et Ubuntu (j’ai les deux aussi) ;
  • au sein du mail reçu, les packages sont clickables et renvoit sur la documentation officielle correspondante ;
  • il doit bien sûr être lancé en root pour pouvoir exécuter les commandes apt-get ;

Résultat du mail.

notify-apt-updates.png

Lancement en cron (par ex. depuis /etc/crontab).

notify-apt-updates-crontab.png

Le script (à mettre dans /usr/bin/notify_apt_updates.sh et à paramétrer) ( notify_apt_updates.sh ).

  1. #!/bin/ksh
  2.  
  3. # ======================================================================
  4. # === Mise à jour
  5. # ======================================================================
  6. echo "--- DEBUT -------------------- $(date) --------------------"
  7. apt-get update
  8.  
  9. # ======================================================================
  10. # === Variables système
  11. # ======================================================================
  12. HOSTNAME=$(hostname)
  13. IP=$(ifconfig | grep "inet ad" | grep -v "127.0.0.1" | head -1 | cut -f2 -d: | awk '{print $1}')
  14. DATE=$(date "+%Y-%m-%d %H:%M:%S")
  15. SYSTEM_NAME=$(lsb_release -a 2>/dev/null | grep -i codename | awk ' { print $2 } ' )
  16. SYSTEM_TYPE=$(lsb_release -a 2>/dev/null | grep -i "distributor id" | awk ' { print $3 } ' )
  17. SYSTEM_TYPE_m=$(echo "${SYSTEM_TYPE}" | tr "[A-Z]" "[a-z]")
  18. MAIL_CONTENT_FILENAME="/tmp/mail_content_$$.txt"
  19. PACKAGES_BASE_URL=""
  20. if [[ "${SYSTEM_TYPE_m}" = "debian" ]] ; then
  21. PACKAGES_BASE_URL="http://packages.debian.org/${SYSTEM_NAME}/"
  22. else
  23. if [[ "${SYSTEM_TYPE_m}" = "ubuntu" ]] ; then
  24. PACKAGES_BASE_URL="http://packages.ubuntu.com/fr/${SYSTEM_NAME}/"
  25. fi
  26. fi
  27.  
  28. # ======================================================================
  29. # === Variables à paramétrer
  30. # ======================================================================
  31. MAIL_FROM="me@hostname"
  32. MAIL_DEST="me@hostname"
  33. MAIL_SUBJECT="Server [${HOSTNAME}] - new updates found"
  34.  
  35. # ======================================================================
  36. # === Corps du traitement
  37. # === Exemple de sortie apt-get si mise à jour :
  38. # === 18 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
  39. # ======================================================================
  40. NB_EN=$(apt-get -s upgrade | egrep ".*upgraded.*newly installed.*remove" | grep -v "0 upgraded" | wc -l)
  41. NB_FR=$(apt-get -s upgrade | egrep ".*mis à jour.*nouvellement installés.*à enlever.*non mis à jour" | grep -v "0 mis à jour" | wc -l)
  42. if [[ "$NB_EN" -eq 0 && "$NB_FR" -eq 0 ]] ; then
  43. echo "No updates found, nothing to notify."
  44. else
  45. echo "Updates found."
  46. PACKAGES=""
  47. HTML_PACKAGES=""
  48. apt-get -s upgrade 2>/dev/null | grep "^Inst" | while read INST PACKAGE DUMMY
  49. do
  50. if [[ ! -z "${HTML_PACKAGES}" ]] ; then
  51. HTML_PACKAGES="${HTML_PACKAGES}, "
  52. PACKAGES="${PACKAGES} "
  53. fi
  54. if [[ ! -z "${PACKAGES_BASE_URL}" ]] ; then
  55. URL='<a href="'${PACKAGES_BASE_URL}${PACKAGE}'">'${PACKAGE}'</a>'
  56. else
  57. URL="${PACKAGE}"
  58. fi
  59. HTML_PACKAGES="${HTML_PACKAGES}${URL}"
  60. PACKAGES="${PACKAGES}${PACKAGE}"
  61. done
  62. echo "Packages to be updated : ${PACKAGES}"
  63. cat << EOF > "${MAIL_CONTENT_FILENAME}"
  64. From: ${MAIL_FROM}
  65. To: ${MAIL_DEST}
  66. Subject: ${MAIL_SUBJECT}
  67. MIME-Version: 1.0
  68. Content-Type: multipart/mixed;
  69. boundary="PAA08673.1018277622/${HOSTNAME}"
  70.  
  71.  
  72. This is a MIME-encapsulated message
  73.  
  74.  
  75. --PAA08673.1018277622/${HOSTNAME}
  76. Content-Type: text/html
  77.  
  78. <html>
  79. <head>
  80. <title>${MAIL_SUBJECT}</title>
  81. </head>
  82. <body>
  83. <table border="0">
  84. <tr>
  85. <td><b>Server</b></td><td>&nbsp;:&nbsp;</td><td>${HOSTNAME} (${IP}) [${SYSTEM_TYPE_m}-${SYSTEM_NAME}]</td>
  86. </tr><tr>
  87. <td><b>Date</b></td><td>&nbsp;:&nbsp;</td><td>${DATE}</td>
  88. </tr><tr>
  89. <td><b>New packages</b></td><td>&nbsp;:&nbsp;</td><td>${HTML_PACKAGES}</td>
  90. </tr>
  91. </table>
  92. </body>
  93. </html>
  94. EOF
  95. echo "Sending mail to : ${MAIL_DEST}"
  96. esmtp -t < "${MAIL_CONTENT_FILENAME}"
  97. fi
  98. echo "--- FIN -------------------- $(date) --------------------\n"

samedi, janvier 1 2011

Quelle solution de backup

backupVoilà, je cherche une solution de backup à installer sur mon environnement réseau, et j’ai du mal à trouver une.

Je liste ci-dessous ce que j’ai à sauvegarder, les outils essayés ou en cours de tests, et quelques pistes de réflexion sur une solution “idéale” pour mon cas de figure.

Ma configuration à backuper :

  • Un PC “serveur” Linux sous Ubuntu 10.10 : sauvegarde de fichiers de configuration, sites web, plusieurs bases de données, repository GIT, données personnelles. Donc des fichiers locaux à sauvegarder (tout /etc, quelques fichiers sous /usr/bin, un /home/user, etc.).
  • Un serveur dédié Linux sous Ubuntu 9.10 en ligne (chez OVH) : sauvegarde de fichiers de configuration, sites web, plusieurs bases de données, repository GIT.
  • Un PC portable sous Linux SUSE Enterprise SLED11 : fichiers de configuration, fichiers personnels, bases de données MySQL, etc.
  • Un netbook sous Windows XP : quelques rares fichiers de configuration.
  • Un plug computer sous Debian : fichiers de configuration.

Mes souhaits pour l’outil de backup :

  • simplicité de configuration (tant pour le serveur principal que pour les machines à sauvegarder) ;
  • installation simple (pas de dépendances compliquées) ;
  • fonctionnement possible en réseau : backup vers une machine centrale, backups croisés, mode push et/ou pull, etc. ;
  • multi-protocoles : sauvegarde de fichiers locaux, de fichiers distants, exports de bases de données, prises de snapshot de repository GiT, CVS et éventuellement SubVersion, etc. ;
  • si possible, facilité d’accès aux fichiers sauvegardés : pas de manipulations compliquées pour récupérer un fichier : comme la récupération est tout de même rare et ponctuelle, ce point est mineur, mais dans l’idéal une récupération directement sur disque serait parfaite ;
  • interfaçage DropBox ou autre (Amazon S3) pour envoi de certains fichiers en ligne ;
  • encryption éventuelle des données sauvegardées ;
  • fonctionnement obligatoire en ligne de commande (configuration + lancement), mais interface de configuration / manipulation à côté envisageable (client lourd ou client web) ;
  • projet actif ;
  • une bonne gestion des erreurs : si quelque chose se passe mal, il faut que j’en sois averti !

Les fonctions dont je n’ai pas besoin et que beaucoup de solutions de backup proposent :

  • gravage des données sur disques ou bandes ;
  • mécanismes de sauvegardes incrémentales / différentielles ;

Bref pour résumer, dans l’idéal, il me faudrait un système de plugins (qui doivent être faciles à écrire / modifier / paramétrer) :

  • plusieurs plugins en entrée quoi sauvegarder (fichiers locaux, fichiers distants, bases de données, outils, etc.) ;
  • plusieurs plugins en sortie où sauvegarder (FTP, SSH distant, machine locale, DropBox, Amazon S3, etc.) ;

Avec simplement un appairage entre éléments en entrée et éléments en sortie (quoi sauvegarder, où).

Les pistes de logiciels existants à ma connaissance :

  • rsnapshot : l’outil que j’utilise actuellement mais qui ne me satisfait clairement pas totalement (configuration laborieuse et peu souple, mauvaise gestion des erreurs, …) ;
  • Unison ;
  • Duplicity + frontal ;
  • Cedar backup ;
  • Backup Manager : voilà bien un projet que je trouve obscur et pas intuitif … pas pour moi ;
  • Backupeur : pas mal, léger, mais tout en shell script (donc difficilement portable, et nécessiterait pas mal d’évolutions) ;
  • rdup ;
  • rdiff-backup ;
  • boxbackup ;
  • dirvish ;
  • backupninja : semble intéressant, à creuser ;

Concernant les outils “bas-niveau”, il y a bien sûr :

  • rsync : répond nativement à une partie des problématiques, sauvegarde différentielle de répertoires locaux ou distants ;
  • dar : Disk ARchive, projet très intéressant, une sorte de tar plus évolué, adapté aux sauvegardes de type backup ;

Ces outils en eux-même ne gèrent pas toutes les problématiques que je souhaite couvrir.

Reste la piste de créer moi-même mon propre système de backup … réflexion en cours, pour le moment je partirais sur :

  • réalisation en Java ;
  • principe client / serveur : dans un premier temps, une partie serveur, exécutable sur une ou plusieurs machines, et dans un deuxième temps un ou plusieurs clients (client lourd / client web) ;
  • le principe de plugins en entrée et en sortie évoqué plus haut ;
  • problème n°1 : la librairie rsync n’a pas de réelle implémentation Java (il y a 2 projets non terminés et qui n’évoluent plus : librsync et jarsync, plus peut-être plus tard java-rsync, mais ce projet n’a encore produit aucun code) ;
  • problèmé n°2 : la librairie dar n’existe pas en Java, donc pas d’usage possible en natif ;
  • ces outils ne seraient donc utilisables, comme les autres commandes systèmes type export de bases de données mysql, que par exécution depuis la couche Java de commandes systèmes, ce qui est évidemment facile à faire, mais tout de même moins élégant (problème de configuration, de multi-plateforme, etc.) ;

Annexes.

A noter un ouvrage chez O’Reilly dédié à cette problématique : backup and recovery.

Backup and recovery (O'Reilly)

Quelques liens en vrac en complément :

Retirer en ligne de commande le password d'un fichier .pdf

PDFPour retirer, sous Linux, le mot de passe d’un fichier .pdf, rien de plus simple. On parle bien ici du cas de figure où l’on est (légalement) en possession de ce password et où on veut simplement rendre l’usage du .pdf plus souple (cas d’un achat en ligne dont le .pdf est verrouillé par un password, password qu’il faut saisir à chaque lecture, ce qui s’avère passablement exaspérant à la longue).

Plusieurs solutions existent mais la plus simple est de passer par qpdf.

Installer qpdf :

sudo apt-get install qpdf

Procéder au retrait du mot de passe :

qpdf --password=xxxxxxx --decrypt fichier_avec_password.pdf fichier_destination.pdf

D’autres solutions existent (conversion .pdf > .ps puis retour en .ps avec xpdf-utils, manipulations avec pdftk, etc.), mais la version en ligne de commande avec qpdf est vraiment la plus simple.

dimanche, décembre 19 2010

La semi-déception du jour : plug computer Ionics Stratus

Après le fiasco des Guruplug trop bruyants - que je m’étais fait remboursés sans problème par NewIT, très corrects dans l’histoire et sans doute très embêtés par les problèmes de retards et de bruits de ces serveurs - j’étais parti sur un autre modèle : un Stratus Plug Computer (sur base de Sheevaplug), produit par une société américaine, Ionics Plug.

Reçus il y a peu, et à nouveau une grosse déception : alors que j’ai bien commandé un modèle compatible avec les prises françaises, c’est un modèle US qui m’a été expédié !

Le pire c’est que :

  • j’ai contacté le service des ventes avant commande, on m’a bien répondu que oui, il était possible d’avoir ces plugs au format européen, mais qu’il y aurait un délai supplémentaire ;
  • je le précise bien lors de ma commande : il me faut deux plugs avec prises françaises ;
  • on me répond immédiatement après ma commande “attention, nous n’avons que des versions avec prises US en stock, que doit-on faire de votre commande ?”, ce à quoi je maintiens ma commande de plugs avec prise françaises, en forwardant le mail initial ;

Et bien malgré tout çà, j’ai quand même reçu (deux mois après ma commande) des plugs avec prises US.

Et le support d’Ionics, recontacté, ne me propose que soit un remboursement, soit … d’aller à la quincaillerie du coin m’acheter des adaptateurs US > FR. Ben voyons.

Comme c’est mon deuxième fiasco sur ce sujet, et que çà commence à me faire cher en frais d’expéditions UK > France, France > UK, US > France, je n’ai pas trop d’autres choix que d’en rester là, mais du coup, avec un adaptateur US > France, impossible de faire tenir le plug au mur comme prévu (avec l’adaptateur, il faut forcément le laisser à plat sur une multiprise au sol (sans quoi, à la verticale, étant relativement lourd, il ne tient pas en place, à cause du poids et du décalage lié à l’adaptateur).

Quant au plug lui-même - qui fonctionne heureusement en 110-220V / 50-60Hz - il fonctionne tout de même bien. Il chauffe, mais il ne fait pas de bruit, c’est déjà çà. Plus d’informations sans doute dans un billet ultérieur

Au passage, les CD-Rom fournis (contenant le kit de développement) sont totalement illisibles (testés sur 3 lecteurs différents). Dommage aussi. Recontacté à ce sujet, le support ne m’a pas donné de réponse sur ce sujet.

Enfin, le packaging sur la boîte n’indique même pas quelles sont les options des plugs à l’intérieur, alors que j’en ai commandé un standard (pas pour moi) et un avec option Zigbee, difficile - sans pouvoir les démarrer pour le problème de prises - du coup de savoir quel boîtier est à qui.

Bref, de mon point de vue, un service commercial pas très efficace de la part d’Ionics.

Donc pour résumer :

  • les Guruplugs sont trop bruyants pour une utilisation normale, mais NewIT, l’importateur UK, a un très bon service ;
  • les Ionics Plugs ne sont pas bruyants du tout (mais chauffent un peu quand même), mais les services logistique et commercial d’Ionics n’est vraiment pas bon : incapables d’envoyer ce qui a été commandé, et incapables de corriger comme il le faudrait leur erreur (au passage, ils auraient suffi qu’ils me réexpédient la pièce - (dé)clipsable, voir photos ci-dessous - qui correspond à la prise elle-même … mais non). Bref, je déconseille finalement de commander auprès de cette société.

Quelques photos du plug en open-the-box pour finir :

Ionics Stratus plug computer

Ionics Stratus plug computer

Ionics Stratus plug computer

Ionics Stratus plug computer

Ionics Stratus plug computer

Ionics Stratus plug computer

Ionics Stratus plug computer

Ionics Stratus plug computer

Ionics Stratus plug computer

dimanche, décembre 5 2010

Accéder à un repository GIT / subversion derrière un proxy authentifié.

Proxy

GIT

Pour accéder à un repository GIT en étant derrière un proxy d’entreprise (avec authentification).

Installer socat.

sudo apt-get install socat

Créer le script git-proxy.sh (dans un répertoire accessible via le PATH courant, ex. /usr/bin) :

#!/bin/bash
HTTP_PROXY_HOSTNAME="url_du_proxy_d_entreprise"
HTTP_PROXY_PORT="port_du_proxy"
HTTP_PROXY_USERNAME="username"
HTTP_PROXY_PASSWORD="password"
socat STDIO PROXY:${HTTP_PROXY_HOSTNAME}:$1:$2,proxyport=${HTTP_PROXY_PORT},proxyauth=${HTTP_PROXY_USERNAME}:${HTTP_PROXY_PASSWORD}

Remarque : il suffit de retirer la partie “,proxyauth” si le proxy ne demande pas d’authentification.

En ligne de commande il suffit ensuite de positionner l’accès au proxy pour GIT :

export GIT_PROXY_COMMAND=git-proxy.sh

Puis de lancer normalement une commande git, par ex. :

git clone git://git.gnome.org/conduit

Subversion

La manipulation est nettement plus simple pour subversion.

Il suffit d’éditer le fichier ~/.subversion/servers, de localiser la paramétrie “[global]” et de décommenter / renseigner ou ajouter les lignes suivantes :

\[global\]
http-proxy-host = url_du_proxy_d_entreprise
http-proxy-port = port_du_proxy
http-proxy-username = username
http-proxy-password = password

dimanche, octobre 17 2010

Retour sur migration d'une partition en ext3 vers ext4 sur une baie RAID5

RAIDSuite au passage sans trop de problèmes en Ubuntu 10.10 ce week-end pluvieux, j’ai franchi le pas aussi pour le format de la partition de ma partition RAID5 qui était jusqu’ici en ext3, que j’ai migrée en ext4.

Ce format de partition me semble aujourd’hui suffisamment stable, je l’utilise depuis Ubuntu 10.04 sur ma partition système sans soucis. Qui plus est, sur cette partition RAID5 en ext3, je rencontrais des problèmes de temps de réponses, notamment des créations de répertoires assez longues, temps que j’espère meilleurs en ext4.

La manipulation pour faire la conversion sans tout reformater est décrite partout sur le web, comme par exemple ici : Convert file system from ext3 to ext4.

Dans mon cas, j’ai migré une partition /dev/md0/ constituée de quatre disques Samsung 1.5TO - soit en pratique 3 disques utiles et 1 spare — pour une taille utilisable de 4.1TO, remplie avant la manipulation à 3.3TO.

/dev/md0      ext4    4,1T  3,3T  749G  82% /mnt/internal/1500go-raid

Au final, la conversion est longue, mais s’est bien passée (j’avais tout de même un backup partiel des données au cas où …).

Etape 1. Un premier fsck pour valider que tout va bien sur la partition durée = __120 minutes__

# sudo e2fsck -pf /dev/md0

Résultat :

/dev/md0 : 964328/274718720 fichiers (3.1% non contigus), 902621888/1098851952 blocs

Etape 2. La conversion des inodes par tune2fs durée = __0 minutes__

# sudo tune2fs -O extents,uninit_bg,dir_index /dev/md0

Etape 3. Un deuxième fsck (obligatoire) durée = __116 minutes__

# sudo e2fsck -pf /dev/md0

Etape 4. Changer le type de la partition de ext3 en ext4 dans /etc/fstab

# sudo vi /etc/fstab

Pour avoir :

/dev/md0                                        /mnt/internal/1500go-raid 	ext4	     defaults,relatime		 0  3

Etape 5. Remontage manuel et/ou reboot.

# sudo mount /dev/md0

A noter la présence d’une floppée d’erreurs “normales” lors de l’étape 3 (voir par exemple ce lien qui confirme que c’est le comportement attendu) :

(...)
Le checksum du descripteur de groupe 33533 est invalide. CORRIGÉ.
Le checksum du descripteur de groupe 33534 est invalide. CORRIGÉ.
Passe 1 : vérification des i-noeuds, des blocs et des tailles

Passe 2 : vérification de la structure des répertoires
Passe 3 : vérification de la connectivité des répertoires
Passe 4 : vérification des compteurs de référence
Passe 5 : vérification de l'information du sommaire de groupe
/dev/md0 : 964328/274718720 fichiers (3.1% non contigus), 902621888/1098851952 blocs

Bien sûr, le bénéfice de cette migration sera moins important qu’après un reformatage complet : c’est seulement au fur et à mesure que les données seront réécrites sur la partition migrée que les optimisations liées à ext4 auront lieu.

En premier test qui ne veut vraiment pas dire grand chose : j’ai un site web stocké sur cette partition RAID5 et qui a une utilisation assez intensive du filesystem. Pour une recherche précise qui mettait 0.08 secondes en ext3, je suis passé maintenant à 0.02 secondes en ext4 ;)

MAJ : par contre petite déception, dans certains cas (profondeur assez importante dans l’arborescence des répertoires), la création d’un nouveau sous-répertoire tout simple n’est toujours pas instantannée en ext4 chez moi. A première vue çà prendrait un poil moins de temps qu’en ext3, mais plus que sur d’autres partitions (je suppose que c’est le nombre de fichiers / répertoires présents sur cette partition qui est pénalisant, au demeurant la partition RAID5 en question se porte très bien et affiche de bonnes perfs’ en lecture/écriture, donc pas de problèmes matériels). A voir dans la durée au fur et à mesure que les données seront réécrites …

samedi, octobre 2 2010

Convertir un enregistrement iPhone .m4a en .mp3 sous linux

m4aRien de plus simple, pour convertir les fichiers audio par ex. enregistrés sur un iPhone en .mp3.

Il suffit d’avoir lame et faad (Advanced Audio Decoder player). Il est bien sûr possible d’en profiter pour utiliser les différentes fonctions de LAME (changement du bitrate, ajout de métadata avec les options tt pour le titre, tg pour le genre, etc.).

sudo apt-get install faad lame

Et de lancer la conversion comme ceci :

faad -o - “fichier_source.m4a” | lame - “fichier_destination.mp3”

Exemple de sortie :

guruplug.m4a file info:

LC AAC	17.120 secs, 2 ch, 44100 Hz

  ---------------------
 | Config:  2 Ch       |
  ---------------------
 | Ch |    Position    |
  ---------------------
 | 00 | Left front     |
 | 01 | Right front    |
  ---------------------

Decoding guruplug.m4a took:  0.04 sec. 427.99x real-time.
LAME 3.98.3 64bits (http://www.mp3dev.org/)
Using polyphase lowpass filter, transition band: 16538 Hz - 17071 Hz
Encoding <stdin> to guruplug.mp3
Encoding as 44.1 kHz j-stereo MPEG-1 Layer III (11x) 128 kbps qval=3

En bonus un petit script qui encapsule cette commande pour réaliser ce traitement en batch en lien externe.

Guru Plug Server Plus : bonne petite machine, mais trop bruyante

La déception du jour : le serveur Guru Plus Server Plus (un plug computer).

Guruplug

Sur le papier c’est une excellente petite machine permettant d’avoir un serveur Linux complet dans un boîtier de la taille d’un boîtier CPL, avec les caractéristiques suivantes :

  • processeur Marvell 1.2Ghz ;
  • 512 mo de RAM interne ;
  • 512 mo de flash interne ;
  • 1x port micro-SD ;
  • 2x ports ethernet Gigabit 10/100/1000 ;
  • Wi-Fi ;
  • bluetooth ;
  • 2x ports USB ;
  • 1x port e-SATA ;

Avec une consommation max donnée à 5W seulement. Le serveur est livré prêt à l’emploi avec une distribution Debian déjà installée.

Et tout çà pour 99$, soit 120 euros port compris chez le revendeur UK NewIT. Bref, une machine très complète pour faire un parfait petit serveur avec de nombreux usages potentiels (serveur de fichier, de mail, routage, domotique, etc.).

Pour l’heure, c’est toutefois une grosse déception. J’ai pré-commandé le boîtier en mai 2010, et les premiers envois ont rapidement été interrompus car il s’est avéré que le boîtier chauffait anormalement, notamment au niveau des connecteurs ethernet (au point de s’y brûler au touché).

La société qui produit le plug, Globalscape, a pris quelques mois pour revoir sa copie avec le fabricant chinois, pour ajouter, sur l’unité dont j’ai reçu un modèle ce jour, un petit ventilateur à l’intérieur. Vu la petite taille du boîtier, ils n’ont évidemment pas pu mettre un gros heatsink et un gros ventilateur, le ventilateur équipé ne fait que 20 mm x 20 mm.

Au final il remplit à peu près son rôle de ventilateur (le boîtier reste cependant après 3 heures de fonctionnement chaud au toucher sur les côtés et le dessus), mais le bruit généré par l’engin est franchement conséquent (bien au delà du niveau sonore de n’importe quel PC traditionnel que j’ai déjà pu entendre).

Une petite vidéo pour se rendre compte (je pense qu’en vrai, c’est encore plus perceptible que sur la vidéo, le .mp3 ci-dessous est d’ailleurs plus représentatif). Le plug s’entend ronronner sans problèmes à plusieurs mètres.


fichier mp3 autonome (enregistrement brut sans altérations)

Qui plus est des tests poussés réalisés par des personnes ayant reçue la première version font état de piètres performances de la partie matérielle, voir ce très bon test sur le sujet : GuruPlug Server Plus : don’t waste your money on it!.

Cela dit, pour mon usage, je pense que les performances de la machine seraient tout à fait suffisantes.

Pour moi, le bruit généré rend ce serveur totalement impropre à l’utilisation auquel je le destinais : avoir un mini-serveur silencieux, ne consommant pratiquement rien, sur lequel faire tourner un certain nombre de services de gestion et de services domotiques sous Linux. Vu sa faible taille, je comptais le mettre entre mon entrée et mon salon, pour y brancher dessus un mir:ror de Violet (lecteur RFID). Le bruit conséquent que génère le serveur rend cet usage impossible. J’hésite entre l’ouvrir et le bidouiller (faisable, mais sans garanties de réussir à mettre en place une bonne dissipation thermique sans bruit, pour au final un boîtier qui risque de devoir resté ouvert ou qui risque d’être découpé de partout, donc on sera loin du concept initial d’un simple boîtier intègre sans câbles) ou le retourner pour remboursement et trouver un autre modèle (peut-être l’ancien modèle, le sheevaplug (qui ne semblait pas souffrir de ces défauts de chauffe), ou un Ionics plug).

Quelques photos en open-the-box :

Guruplug - La boîte

Guruplug - les câbles

Guruplug - Découverte du plug

Guruplug - Le plug de près

Guruplug - Le dos du plug

Au déballage, pas de soucis pour s’en servir, bien qu’il n’y ait aucune documentation fournie avec le packaging.

Le serveur boote en moins de 30 secondes et, avec la configuration par défaut, se retrouve en Wi-Fi “Access Point”, ce qui fait qu’il suffit de se connecter dessus en ssh, par exemple depuis un PC portable en WiFi (en prenant le réseau ouvert par le guruplug, quelque chose du genre Plug2-uAP-1713) :

ssh root@192.168.1.1

Le mot de passe root par défaut étant “nosoup4u”.

Et en liens annexes … :

mardi, août 3 2010

Optimisations web et outils associés

Venant de découvrir ShowSlow (un site qui aggrège les données remontées par YSlow et Page Speed, voir ci-dessous), j’en ai profité pour appliquer cette astuce toute bête sur tous mes sites qui le permettent et qui n’étaient pas forcément à jour.

Au programme dans ce billet : une optimisation toute simple de l’usage du cache pour toutes les ressources (par .htaccess), et le rappel de quelques outils d’aide au diagnostic (que j’imagine tous les développeurs web connaissent, mais sait-on jamais) : YSlow, Page Speed, ShowSlow et WebPageTest.

Tous ces outils sont intéressants, mais il ne faut pas s’attendre à avoir des gains de performances de l’ordre de 100%. Par ailleurs, ces outils se focalisent tous sur l’analyse des performances côté navigateur, il ne faut pas oublier l’analyse et les optimisations côté back-office.

Optimisation de l’usage du cache pour toutes les ressources (par .htaccess)

Le principe consiste, pour optimiser la conservation en cache des ressources statiques commes les images, les .css ou les .js, à forcer une durée de rétention importante via une directive stockée dans un .htaccess

Avantages : tous les fichiers du site (ou du répertoire concerné par le .htaccess) sont automatiquement paramétrés avec ce délai d’expiration. Les fichiers resteront donc systématiquement dans le cache du navigateur (jusqu’à purge manuelle ou expiration de la durée indiquée).

Inconvénient : il ne sera en l’état pas possible de modifier ces fichiers. Autrement dit si un de ces fichiers est modifié en ligne, il ne sera pas récupéré par les visiteurs qui seront déjà venus précédemment sur le site (mais des solutions existent, sur une base de versionning de fichiers, voir cet excellent article de ce non moins excellent blog).

Le code à mettre dans le fichier .htaccess (à adapter au besoin sur le type de fichiers concernés et la durée de conservation dans le cache) :

<IfModule mod_expires.c>
SetEnv mod_expires On
ExpiresActive On
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
</IfModule>

Installation du module expire sous Apache :

sudo a2enmod expires 

That’s all !

En utilisant les outils ci-dessous (et en partant à chaque fois d’un cache vide) on constate bien une (légère) différence de temps de chargement, et différence dans les résultats d’analyse.

Outillage en rapport.

YSlow

YSlowYSlow est une extension FireFox qui enrichit le plugin FireBug, Le principe est ensuite, une fois une page analysée, de lister un certain nombre d’éléments pertinents à corriger / modifier pour obtenir de meilleures performances, notamment (tout est rappelé sur la page Best practices for speeding up your web site) :

  • réduire le nombre de requêtes HTTP = concaténer les fichiers qui peuvent l’être (.css, .js) ;
  • paramétrer correctement les expirations de cache (cf. ci-dessus par ex.) ;
  • mettre en place une compression GZip (soit au sein du framework utilisé (la plupart le permette), soit par soi même (en PHP via les méthodes de capture de flux, etc.), soit encore par une paramétrie globale par ex. côté Apache) ;
  • mettre les feuilles de style en début de page ;
  • et les scripts en bas de page ;
  • rendre les ressources .css et .js externes (afin qu’elles puissent être mises en cache) et les compresser (avec Google Closure ou YUI Compressor) ;
  • etc.

Page Speed

Page TestAutre extension pour FireFox, toujours sous forme d’ajout à FireBug, toujours sur le même principe : analyser la page, et faire une liste de recommandations en conséquence.

Au final j’ai quand même plus tendance à utiliser YSlow et à me passer de Page Speed, même si certains trouvent certains avantages à Page Speed. Evidemment, çà ne coûte pas grand chose d’installer les deux (les deux s’intégrant parfaitement dans FireBug) et de faire une passe sur son site avec chaque outil (qui ne prend qu’une ou deux secondes).

Le site de Page Speed : http://code.google.com/intl/fr-FR/speed/page-speed/

Showslow

Show SlowIl s’agit d’un site (à installer soi-même sur son serveur), développé en PHP, et qui permet d’historiser les valeurs remontées par YSlow et Page Speed, en automatique (une fois son FireFox correctement configuré). Ce n’est clairement pas indispensable, mais çà permet d’avoir un historique des performances de ses sites web.

Il suffit de suivre la documentation d’installation, bien faite et tout à fait suffisante, pour installer la coeur de l’outil, et d’ensuite paramétrer les deux plugins FireBug en conséquence.

WebPageTest

Web Page TestDécouvert pour ma part dans la foulée de ShowSlow, WebPageTest permet de faire le même type d’analyses, certes en moins poussé, mais déclenchées cette fois en ligne, et surtout avec deux avantages notables :

  • les tests peuvent se faire depuis des machines hébergées en différents points du globe (Paris, Amsterdam, différentes villes en Amérique, la Chine, la Nouvelle-Zélande, …) ;
  • il est possible de tester l’accès à sa page sur différents navigateurs.

lundi, août 2 2010

Extraire en java les données stockées dans JIRA

JIRACette semaine, j’ai passé un peu de temps au boulot à travailler sur l’extraction de données stockées dans JIRA, en Java. Pour rappel, JIRA est un système de suivi de bugs, un système de gestion des incidents, et un système de gestion de projets, fourni par Atlassian, et c’est bien sûr le système que l’on utilise dans ma boîte. Dans le cadre d’un nouveau projet dont je m’occupe, pour lequel je stocke sous JIRA l’ensemble des tâches à réaliser par toute l’équipe, j’ai besoin d’extraire toutes les informations liées à chacune de ces tâches pour construire en automatique un planning GANTT.

JIRA (Atlassian)

Remarque : il y a bien un plugin officiel pour JIRA orienté “gestion de projet”, il s’agit de Greenhopper, malheureusement il est payant et il n’est pas envisagé aujourd’hui de s’en équiper chez nous.

Atlassian fournit donc plusieurs mécanismes pour interagir avec JIRA (en action - création de nouvelles tâches par ex. - et/ou en extraction). A ma connaissance il y a :

  • l’API XML-RPC ;
  • l’API SOAP ;
  • les flux XML et RSS directement depuis le serveur JIRA ;
  • les Jelly Scripts.

En préambule, il est conseillé de jeter un oeil sur la page How JIRA works.

XML-RPC

XML-RPC est un protocole d’interaction (Remote Procedure Call) permettant d’inteagir par XML avec le système. En lui même, c’est donc juste un ensemble de méthodes à utiliser par des appels XML. Autrement dit utilisable avec n’importe quel langage.

Une documentation JIRA présente ce protocole : JIRA, XML-RPC Overview.

Une implémentation (non-officielle) est par ailleurs disponible en Java et fonctionne parfaitement bien : il s’agit de la librairie Swizzle [http://swizzle.codehaus.org/Home ].

J’avais déjà réalisé un traitement Java avec cette librairie il y a quelques mois, pour récupérer l’ensemble des fiches JIRA liées à une version projet et créer en automatique de nouvelles fiches.

L’utilisation de la librairie Swizzle est cependant très simple, exemple de connexion :

  1. try {
  2. org.codehaus.swizzle.jira.Jira jira = new Jira(url);
  3. jira.login(username, password);
  4. } catch (MalformedURLException e) {
  5. throw new BaseException(e);
  6. } catch (Exception e) {
  7. throw new BaseException(e);
  8. }

Et un exemple de récupération de données sur une recherche libre (il y a bien sûr d’autres méthodes pour récupérer les données) :

  1. Vector v = new Vector();
  2. v.add("CLE_DU_PROJET_JIRA"); // le ou les projets sur lesquels faire la recherche
  3. String critereDeRecherche = ""; // On ramène toutes les fiches JIRA
  4. int nbFichesARamener = 1000; // nombre max de fiches JIRA à récupérer
  5. List issues = jira.getIssuesFromTextSearchWithProject(v, critereDeRecherche, nbFichesARamener);

Ensuite la plupart des informations se retrouvent sur l’objet Issue correspondant. Il y a bien sûr des objets Java pour représenter les Versions JIRA, les filtres, les utilisateurs, le projet JIRA, etc.

Le seul problème vient du fait que toutes les opérations / informations disponibles sous JIRA ne le sont pas au travers de l’API XML-RPC, notamment dans le cas qui m’intéresse, les informations relatives aux sous-tâches et aux champs personnalisés ne sont pas exportées, donc obligé de faire autrement, d’où le switch sur la 2e API proposée par Atlassian, via SOAP.

SOAP

Il s’agit d’une API externe également, avec cette fois une implémentation Java “officielle” fournie par Atlassian (ainsi qu’une implémentation Python, au passage).

La mise en place est moins évidente qu’avec Swizzle, puisqu’il en faut ici :

  • récupérer le projet SOAP client en ligne ;
  • récupérer le fichier WSDL sur le serveur JIRA sur lequel on veut se mapper (fichier décrivant l’ensemble des services disponibles) ;
  • utiliser un profile Maven pour générer à partir de ce fichier WDSL les classes Java (dans “target/generated-classes/*.class”) correspondant aux services disponibles ;
  • toujours avec Maven, mettre à jour le .classpath Eclipse ;
  • pouvoir enfin utiliser les objets natifs Java permettant d’interagir avec JIRA via SOAP ;
  • plus en bonus, mettre en place un packaging sous forme de .jar de ces classes générées pour ne pas avoir à refaire ces manipulations à chaque fois (à faire par soi même) ;

Toutes ces opérations sont détaillées dans la documentation en ligne Atlassian : Creating a SOAP Client pour la présentation générale de l’API SOAP et dans le README du projet exemple pour le détail des manipulations techniques.

S’il n’y a rien de compliqué, c’est moins simple que de simplement ajouter une dépendance comme Swizzle, mais cela a l’avantage de construire une API de services correspondant réellement aux services disponibles sur le serveur JIRA utilisé, quelle que soit la version de ce dernier.

L’usage de ce client Java SOAP est très simple également et ressemble bigrement à l’API XML-RPC, exemple pour la connexion :

  1. String url = "http://jira.domaine.tld/";
  2. String username = "login de servitude";
  3. String password = "password du compte de servitude";
  4. (...)
  5. JiraSoapServiceService jiraSoapServiceLocator = new JiraSoapServiceServiceLocator();
  6. JiraSoapService jiraSoapService = null;
  7. String authToken; // il est important de garder ce auth token, toutes les méthodes en auront besoin ensuite
  8. RemoteType[] remoteTypes; // on va conserver en local la liste des types disponibles au niveau du projet
  9. // pour pouvoir ensuite facilement retrouver à quoi correspondant le type d'une tâche
  10. RemoteStatus[] remoteStatuses // Idem pour les status
  11. try {
  12. if (url == null) {
  13. jiraSoapService = jiraSoapServiceLocator.getJirasoapserviceV2();
  14. } else {
  15. jiraSoapService = jiraSoapServiceLocator.getJirasoapserviceV2(url);
  16. log.info("SOAP Session service endpoint at " + url.toExternalForm());
  17. }
  18.  
  19. authToken = getJiraSoapService().login(username, password);
  20. remoteTypes = getJiraSoapService().getIssueTypes(getAuthToken());
  21. remoteStatuses = getJiraSoapService().getStatuses(getAuthToken());
  22. } catch (ServiceException e) {
  23. throw new BaseException("ServiceException during SOAPClient contruction", e);
  24. } catch (RemoteAuthenticationException e) {
  25. throw new BaseException("RemoteAuthenticationException during SOAPClient contruction", e);
  26. } catch (RemoteException e) {
  27. throw new BaseException("RemoteException during SOAPClient contruction", e);
  28. } catch (java.rmi.RemoteException e) {
  29. throw new BaseException("RemoteException during SOAPClient contruction", e);
  30. }

Et pour comparaison, la récupération de données dans JIRA (qui ressemble toujours bigrement à la méthode précédente) :

  1. RemoteIssue[] issues;
  2. int nbFichesARamener = 1000; // nombre max de fiches JIRA à récupérer
  3. try {
  4. issues = getJiraSoapService().getIssuesFromTextSearchWithProject(getAuthToken(), new String[] { project.getKey() }, "", nbFichesARamener);
  5. } catch (RemoteException e) {
  6. throw new BaseException(e);
  7. } catch (java.rmi.RemoteException e) {
  8. throw new BaseException(e);
  9. }

Malheureusement, toujours les mêmes limitations : de nombreuses informations ne sont pas disponibles.

Visiblement je ne suis pas le seul à le déplorer, on trouve de nombreuses issues ouvertes chez Atlassian sur ce sujet … certaines depuis 2005 (voir par ex. ce thread sur Stackoverflow.com et celui-ci dans le forum JIRA et un patch a même été développé).

Donc à ce stade après avoir passé quelques heures à jouer avec le mécanisme SOAP, je n’ai toujours pas moyen de récupérer toutes les informations dont j’ai besoin.

Si les solutions officielles et “propres” fournies par les API JIRA ne fonctionnent pas, il va alors falloir revenir à quelque chose de plus simple : les exports XML.

Bonus : un tutorial très détaillé pour l’utilisation de l’api JIRA SOAP, Vérifier le JIRA avant de faire la release.

XML

Un peu partout dans JIRA, on peut trouver des liens “RSS” et “XML” qui exportent les données JIRA correspondant à la recherche courante. En regardant le contenu, on voit que cette fois il y a bien absolument toutes les informations nécessaires, y compris les champs supplémentaires et les informations sur les sous-tâches (à l’exception notable de la “date de démarrage”, mais je peux m’en passer).

Il suffit donc de mettre en place une récupération par HTTPClient pour récupérer le flux XML, et de le parser (dans mon cas avec la très bonne API simple-xml, qui permet de facilement mapper dans les deux sens du XML vers des beans java par simples annotations) pour récupérer toutes les infos souhaitées. Ca marche mais c’est moins rigoureux, il faut notamment récupérer les informations de type “date” sous une forme textuelle et faire un parsing dessus (autrement dit le format des dates peut changer à la faveur d’une montée de version du serveur, par ex.). Mais vu que je n’ai pas trop le choix …

Il faut bien sûr toujours avoir un compte qui puisse accéder par HTTP aux pages JIRA (dans mon cas, un “compte de service” que j’ai créé uniquement à cet usage, pour ne pas avoir à utiliser mon identifiant réseau propre).

Exemple de récupération du flux XML par HTTPClient :

  1. String host = "jira.domaine.tld";
  2. String username = "login de servitude";
  3. String password = "password du compte de servitude";
  4.  
  5. final GetMethod method = new GetMethod(url);
  6. try {
  7.  
  8. final HttpClient client = new HttpClient();
  9. client.getHostConfiguration().setHost("host", 80, "http");
  10. final Credentials defaultcreds = new UsernamePasswordCredentials(username, password);
  11. client.getState().setCredentials(new AuthScope(host, 80, AuthScope.ANY_REALM), defaultcreds);
  12. method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false));
  13.  
  14. int statusCode = client.executeMethod(method);
  15.  
  16. InputStream responseBody = method.getResponseBodyAsStream();
  17. InputStreamReader reader = new InputStreamReader(responseBody);
  18.  
  19. Serializer serializer = new Persister();
  20. JIRAXMLRss rss = serializer.read(JIRAXMLRss.class, reader);
  21.  
  22. return rss.getChannel().getItems(); // Retourne une liste de beans "maison" alimentés depuis le XML par SimpleXML
  23. } catch (HttpException e) {
  24. throw new BaseException(e);
  25. } catch (IOException e) {
  26. throw new BaseException(e);
  27. } catch (Exception e) {
  28. throw new BaseException(e);
  29. } finally {
  30. method.releaseConnection();
  31. // autres releases ...
  32. }

Mise en place.

Au final - les quelques lignes de code ci-dessus n’étant que des exemples, comme j’avais déjà codé le tout, j’ai fini par garder les 3 implémentations et pouvoir ainsi facilement en switcher selon les usages (je ne détaille pas plus avant, ce post se voulant seulement une présentation des manières d’accéder à JIRA en Java).

Annexes

Jelly scripts

Les scripts Jelly sont des scripts XML exécutables, permettant de réaliser des opérations à partir d’un formalisme XML. C’est un projet Apache, implémenté dans JIRA, mais surtout pour des opérations de type export / import. Je connaissais pour avoir déjà été amené à utiliser ce mécanisme dans le cadre d’une migration Bugzilla vers JIRA lorsque l’on a switché sur ce dernier, mais les fonctions proposées sont plus orientées traitement de masse et semblent ne pas tout couvrir non plus, j’ai donc laissé tomber.

Des exemples de Jelly scripts.

Extension du serveur JIRA.

Comme je n’ai pas la main sur le serveur JIRA (impossible d’y modifier quoi que ce soit de mon côté), je n’ai pas pu déployer cette extension qui aurait corrigé mon problème : Jira Extended Webservice.

C’est un patch qui apporte la gestion des sous-tâches sur l’API SOAP, développé par un utilisateur externe à Atlassian. Voir également le Google Group correspondant.

Bonus

En side point, une présentation vidéo intéressante sur la construction du client lourd JIRA : Killer JIRA CLI.

samedi, juillet 24 2010

Achat d'équipement moto en allemagne

Triumph Speed TripleSi vous cherchez de l’équipement ou du matériel moto pas trop cher, et de qualité, les chaînes de magasins allemands peuvent être une piste intéressante. En France il n’y a que peu de concurrences, à part Dafy Moto.

Il y a (à ma connaissance seulement) deux grandes chaînes de ce type en allemagne : Polo et Louis.de.

Toutes deux possèdent d’innombrables boutiques en allemagne (et parfois en suisse), dont certaines près de la frontière franco-allemande, ainsi qu’un site web dédié. Depuis peu, les deux sites internet sont intégralement disponibles en anglais.

On trouve de tout dans ces enseignes : vêtements moto, casques, bagagerie / sellerie, outils, pièces de rechanges, bottes, etc., à des prix parfois très intéressants, même si certains articles sont parfois au même prix qu’en France. Il y a cependant bien plus de choix de modèles, tailles, etc. que chez un concessionnaire moto classique en France.

Louis.de

URL : http://www.louis.de/

Avantages :

  • Vaste choix de produits ;
  • Marques “maison” de bonne qualité (Streetfighter, Probiker) et à prix très agressifs ;
  • Catalogue .pdf disponible en ligne ;
  • Tous les mois, une brochure présentant des promotions (valables pour les 2 prochains mois) sur un ensemble de produitsn divers (avec parfois des remises conséquentes) est éditée (consultable en ligne ou envoyée par la poste pour les clients, y compris en france) (exemple) ;
  • Tous les 2, 3 mois, une promotion par email est envoyée du type “-15% ou -20% sur l’article de votre choix” pendant un week-end : c’est une vraie bonne occasion d’avoir une grosse réduction sur un produit cher (comme un casque haut-de-gamme) (réduction valable en boutique ou en ligne) ;
  • Présence de boutiques frontalières : Weil-Am-Rhein (tout près de Saint-Louis ou à 20 minutes de Mulhouse), Kehl ;
  • Le magasin de Weil-Am-Rhein auquel j’ai l’habitude de me rendre est gigantesque (aussi grand qu’un Décathlon en France) et une bonne moitié des vendeurs parlent français ; le magasin ferme à 20h en semaine ce qui est pratique pour y aller après le boulot ;
  • Carte de fidélité plutôt intéressante qui rapporte des euros tous les ans en proportion à la somme dépensée chez eux.

Inconvénients :

  • Frais de port un peu élevés pour une commande par internet vers la France (la dernière fois, j’en ai eu pour 14€95).

Louis.de

Polo

URL : http://www.polo-motorrad.de/

Avantages :

  • Présence de boutiques frontalières : Lorräch (à 10 minutes de Saint-Louis ou à 15 minutes de Mulhouse), Kehl ;
  • Site internet bien gaulé, disponible en allemand / anglais ;
  • Bon choix de produits également ;
  • Marque maison “FLM” pas trop mal non plus.

Inconvénients :

  • Magasin de Lorräch un peu petit, et les vendeurs n’y parlent pas français (on arrive tout de même évidemment à se faire comprendre sans problèmes en anglais, mais pour une question technique précise, c’est plus simple chez Louis.de à Weil-Am-Rhein) ;
  • A ma connaissance, moins de promos que chez Louis.de.

Polo.de

Catalogues

Ces deux chaînes éditent par ailleurs un imposant catalogue papier (largement aussi épais / volumineux qu’un catalogue de la Redoute), mais avec, donc, uniquement des accessoires moto.

Jusqu’à il y a peu il était possible de recevoir un catalogue “Polo” gratuitement par la Poste, y compris pour les résidents Français, ce n’est désormais plus le cas. L’envoi d’un catalogue “Louis.de” par la poste vers la France coûte un peu moins de 10 euros. Il y en a évidemment des palettes entières en libre distribution dans tous les magasins.

Louis.de, catalogue Polo.de, catalogue

Conclusion

Personnellement, résidant dans l’est de la France, je me rends typiquement à Weil-Am-Rein pour le magasin Louis.de et à Lörrach pour le magasin Polo, j’y ai acheté mon casque (un Schuberth R1 mat avec visière pare-soleil intégrée, pas mal), des bottes d’été, des gants, un rail “Motoboy II” Telefix pour déplacer facilement la moto au fond du garage (un peu cher mais diablement pratique), …).

Bref si vous cherchez à vous équiper en matériel moto et que vous voulez du choix, je vous conseille de faire un tour chez Louis.de, de vous inscrire à leur newsletter et à leur brochure, et de guetter les promos qu’ils font régulièrement.

Quelques services intéressants à installer sur un serveur Linux

Voici la présentation de quelques services qu’il peut être à mon sens intéressant / pertinent d’installer sur un serveur Linux (je suis pour ma part sous Ubuntu 9.04 et 10.04, et j’installe ces services sur toutes mes machines) : ShellInABox, HDDTemp, Monit, Logwatch, DenyHosts & Fail2Ban.

De nombreux tutoriaux détaillés sont disponibles sur le net pour ces services (quelques pointeurs figurent ci-dessous), mais l’installation de ces cinq outils est de toutes façons très simple.

ShellInABox

Permet d’avoir un accès SSH depuis une page web sur sa machine, autrement dit :

  • d’accéder par SSH à une machine même si un proxy / firewall bloque le port SSH par défaut (cas d’un réseau d’entreprise par ex.) ;
  • de ne pas forwarder vers l’extérieur depuis sa machine le port SSH par défaut (pour éviter les tentatives d’intrusions) tout en gardant un accès SSH ponctuel (sur un autre port que d’éventuels hackers devront connaître pour tenter une intrusion, et qui plus est, ne répondant pas au protocole SSH mais HTTP, ces tentatives intrusions seront moins facilement automatisables) (cas de figure d’un PC à la maison dont certains services sont publiés (ex. le serveur web), mais pas tous) ;

Lien : http://code.google.com/p/shellinabox/

D’autres projets du même style existent mais bien moins aboutis (notamment niveau installation) (par ex. ajax web shell).

Ici ShellInABox gère tout par lui même : c’est un démon qui génère le rendu d’IHM et non un mapping Ajax sur une page servie par Apache.

L’installation est du coup très simple (un package qui fonctionne “out of the box” est disponible sous Ubuntu, y compris 64bits, et la documentation d’installation est en ligne sur le Google Code du projet).

A l’usage, c’est au final très réactif ! (j’ai été bluffé par la vitesse d’affichage, je m’attendais à quelque chose de poussif, à l’usage c’est tout à fait utilisable).

Le seul souci que je n’ai pas encore terminé de résoudre est la gestion du certificat, afin d’avoir un certificat valide et ne plus avoir l’alerte de sécurité qui apparaît quand on passe par l’URL “https” (mais ce n’est en rien gênant au demeurant).

Shell In A Box

HDDTemp

Petit outillage permettant d’obtenir la température des disques. Vu que j’ai 5 disques en RAID-5 collés les uns sur les autres à l’intérieur de mon serveur à la maison, çà m’intéressait de savoir à quelle température ils montent. Je monitore ces valeurs avec DomotiGa, qui m’envoit un mail si la température dépasse un certain seuil (paramétrable).

DomotiGa

Disponible dans toutes les distributions, par ex. sous Ubuntu / Debian :

sudo apt-get install hddtemp

L’utilisation en ligne de commande est tout à fait possible, ex. :

hddtemp /dev/sd?

Donnera :

/dev/sda: WDC WD360GD-00FNA0: 35°C
/dev/sdb: ST31500341AS: 30°C
/dev/sdc: ST31500341AS: 33°C
/dev/sdd: ST31500341AS: 31°C
/dev/sde: SAMSUNG HD154UI: 22°C
/dev/sdf: SAMSUNG HD753LJ:  lecteur connu, mais il ne possède pas de capteur de température.
/dev/sdg: SAMSUNG HD753LJ: 32°C

Monit

Outil de surveillance très pratique, permettant de détecter certains problèmes (process absents, surconsommation) et d’agir en conséuqnce.

Je paramètre ainsi essentiellement les applications soit dans un état “peu stable” (qui peuvent donc planter occasionnellement), soit dont je veux être sûr qu’elles soient toujours accessibles. De fait, je ne déclare même pas les applications très stables comme Apache2, même si dans l’idéal le mécanisme de redémarrage en cas de surchage CPU peut être intéressant (pour éviter qu’Apache tourne en boucle pendant des heures sur un script PHP parti en vrille, etc.).

Sont donc paramétrés sur ma machine de développement :

  • l’interface web sonos qui me permet de piloter mon audio-multiroom, un système Sonos (interface non-officielle écrite en PERL, interfacée sur le réseau en UPnP, et qui plante ponctuellement) ;
  • le serveur domotique DomotiGa, encore balbutiant, et dont je souhaite qu’il soit constamment en ligne (pour enregistrer les événéments domotiques qui passent sur le réseau) ;
  • ShellInABox, pour être sûr de toujours avoir un accès SSH de secours ;
  • mon media player pour la Playstation 3 (PS3), ps3mediaplayer, très efficace au passage ;

Monit

Logwatch

Logwatch permet, une fois paramétré, de recevoir par mail des informations sur sa machine :

  • recherche d’erreurs au sein des logs ;
  • récapitulatif des installations systèmes (via apt, etc.) ;
  • détail des comptes s’étant connecté sur la machine ;
  • occupation disque ;
  • etc. ;

Le tout est paramétrable (bien que la configuration soit un peu bordélique), le seul souci du système étant qu’il finit par envoyer chaque jour un mail, et qu’au final on ne les ouvre jamais, je n’ai pas réussi jusqu’ici à n’avoir des alertes que pour les événements réellement importants (comme un problème hardware sur les disques).

DenyHosts & Fail2Ban

Deux outils plus ou moins complémentaires (leur couverture fonctionnelle se recoupe tout de même en partie), qui permettent de bannir automatiquement toutes les adresses IP qui réalisent des opérations “louches” sur ma machine.

DenyHosts agira uniquement sur analyse des logs de connexion SSH et placera les tentatives répétées (et en échec) de connexion par SSH dans le fichier /etc/hosts.deny pour définitivement bloquer les IPs correspondantes. Fail2Ban monitore quant à lui plus de type de logs différentes (dont celles liées à PHP, Apache, …) et agira en modifiant les règles iptables. Ci-dessous un tutoriel rapide pour l’installation de Fail2Ban.

Ces deux outils gagnent vraiment à être installés, même avec la configuration initiale (ils gagnent bien sûr à être customisés selon les cas de figures et selon ce que l’on peut constater dans les logs Apache par ex. (fail2ban permet notamment de bloquer les attaques Apache w00tw00t).

Extrait de log remontée par Logwatch à propos de DenyHosts et Fail2Ban :


 --------------------- Denyhosts Begin ------------------------

 new denied hosts:
    217.16.83.178
    188.187.7.37

 ---------------------- Denyhosts End -------------------------


 --------------------- fail2ban-messages Begin ------------------------


 Banned services with Fail2Ban:                          Bans:Unbans
   ssh:                                                    [  1:1  ]

 ---------------------- fail2ban-messages End -------------------------


 --------------------- httpd Begin ------------------------


 Requests with error response codes
   400 Bad Request
      /w00tw00t.at.ISC.SANS.DFind:): 11 Time(s)

 ---------------------- httpd End -------------------------


 --------------------- Named Begin ------------------------


 **Unmatched Entries**
   error (unexpected RCODE SERVFAIL) resolving 'ns1.mymmode.com/A/IN': 209.183.52.21#53: 1 Time(s)
   error (unexpected RCODE SERVFAIL) resolving 'ns2.mymmode.com/A/IN': 209.183.52.20#53: 1 Time(s)
   success resolving '50.91.247.82.in-addr.arpa/PTR' (in '91.247.82.in-addr.arpa'?) after disabling EDNS: 1 Time(s)

 ---------------------- Named End -------------------------

Migration technique du serveur dédié terminée

Serveur dédiéDepuis deux ans et demi, je disposais d’un serveur dédié “Kimsufi” chez OVH. Il s’agissait d’un serveur Kimsufi Reloaded 08, processeur “Intel Celeron 220 1.2Ghz”, 1GO de RAM DD2, 250GO de disque dur, bande passante garantie de 100 mbits/secondes.

Ces caractéristiques peuvent ne pas sembler très puissantes, mais pour un serveur déporté et pour mon usage, c’est largement suffisant. Je m’en sers en effet pour, principalement :

  • héberger ce blog et plusieurs autres sites / services sur d’autres noms de domaines sur un serveur Apache2 / PHP5 ;
  • faire tourner des sites J2EE sur un serveur Tomcat6 (il est difficile sinon de trouver où héberger de tels sites sur des offres mutualisées) ;
  • faire office serveur de backup distant pour sauver en ligne certains fichiers (photos, documentations, etc.) que je ne souhaite pas perdre en cas de problème chez moi - bien que mon serveur Linux “at home” tourne en RAID5 - celà me permet d’avoir une sauvegarde déportée et d’accéder au besoin à ces fichiers de partout ;
  • comme repository de codes sources (historiquement, d’abord sous CVS, puis Subversion et maintenant uniquement GiT), ce qui me permet de récupérer de partout mon travail ;

Installé il y a 2 ans et demi sur un Ubuntu 8.04 32bits, j’ai profité d’une baisse de tarifs chez OVH (grâce à la concurrence acharnée avec Dedibox qui propose une offre très similaire), pour prendre un autre serveur dédié de même catégorie (toujours un Kimsufi), ce qui m’a permis, outre de bénéficier d’une réduction de quelques euros par mois, d’avoir un serveur avec les mêmes caractéristiques de base mais le double de RAM (toujours bon à prendre pour Tomcat), et de facilement pouvoir migrer le système en Ubuntu 10.04 64bits, ayant accès aux deux machines en parallèle pendant quelques jours.

Autant j’ai toujours été très déçu des prestations d’OVH en matière d’hébergement mutualisé, autant je n’ai jamais eu de problèmes avec leurs offres de serveurs dédiés.

La migration quant à elle s’est au final très bien passée (une grosse soirée de migration).

En effet, je m’étais créé lors de ma première installation d’une machine de ce type un petit script de post-paramétrie d’un serveur dédié (qui sera peut être détaillé dans un billet futur), à base de SHELL et d’ANT, qui me permet depuis une machine cliente chez moi de facilement appliquer en automatique toutes la paramétrie dont je veux disposer, soit (en vrac et de manière non exhaustive) :

  • création des comptes systèmes et application de la paramétrie correspondante (dont publication des clés SSH) ;
  • installation des packages souhaités et retraits des packages inutiles ;
  • sécurisation de base du serveur (pas d’accès ssh pour root, etc.) ;
  • création des users et bases MySQL ;
  • création des VirtualHost Apache ;
  • installation et paramétrie d’un certain nombre de services (fail2ban, denyhosts, monit, …) ;
  • installation de Dropbox ;
  • etc.

Ensuite, une fois la base du serveur configuré, j’ai juste eu à :

  • modifier mes DNS chez BookMyName pour les faire pointer sur la nouvelle IP ;
  • ne rien faire pour la partie messagerie (toujours une plaie à configurer) vu qu’elle est liée au domaine chez Google Apps (c’est l’intérêt même de ce système, disposer d’une messagerie, paramétrée aux niveaux du domaine (sur les DNS) et donc indépendantes du serveur qui est réellement lié à ce domaine) ;
  • migrer le coeur des données : recopie par SSH des répertoire www d’Apache, export / réimport manuel du contenu des bases de données MySQL, etc. ;
  • remise en place manuelle de la rare configuration qu’il me restait à faire ;
  • vérifier que tout fonctionne ;) (rien de grave à déplorer) ;

Enfin, par sécurité, avant de libérer l’ancien serveur dédié, j’ai fait un backup complet de ce dernier, que je conservé en local quelques jours, au cas où j’aurais oublié un fichier de paramétrie quelque part. Soit un .tar complet du système :

sudo tar cvvzf /backup.tar.gz / --exclude /proc --exclude /backup.* --exclude /sys --exclude /dev --exclude /media --exclude /mnt --exclude /tmp --totals --show-omitted-dirs >> /backup.log 2>&1 &

- page 1 de 2