Sam & Max: Python, Django, Git et du cul » Administration System http://sametmax.com Deux développeurs en vadrouille qui se sortent les doigts du code Wed, 05 Feb 2014 14:20:37 +0000 en hourly 1 http://wordpress.org/?v=3.3.1 Virtualenv EnvironmentError: mysql_config not found sous MAC OSX http://sametmax.com/virtualenv-environmenterror-mysql_config-not-found-sous-mac-osx/ http://sametmax.com/virtualenv-environmenterror-mysql_config-not-found-sous-mac-osx/#comments Tue, 04 Feb 2014 10:56:18 +0000 Max http://sametmax.com/?p=8963 Comme le post précédent est inutile j’en fait un autre qui doit concerner au moins 0.00001% de la population.

A vous qui essayez depuis 2 heures de configurer MySQL-python sous votre virtualenv, cet article vous est dédié.

Cette erreur vicieuse m’arrive à chaque fois que j’installe MySQL-python dans un nouvel environnement virtuel. Ceci dit vous l’aurez peut-être sous un autre OS. Sur centos j’avais qu’à faire un yum install mysql-devel mais sous Mac c’est autre chose. Plus de puissance engendre plus de responsabilités…

 
Max $  pip install MySQL-python
Downloading/unpacking MySQL-python
  Downloading MySQL-python-1.2.5.zip (108Kb): 108Kb downloaded
  Running setup.py egg_info for package MySQL-python
    sh: mysql_config: command not found
    Traceback (most recent call last):
      File "<string>", line 14, in <module>
      File "/Users/Max/.virtualenvs/zooscator/build/MySQL-python/setup.py", line 17, in <module>
        metadata, options = get_config()
      File "setup_posix.py", line 43, in get_config
        libs = mysql_config("libs_r")
      File "setup_posix.py", line 25, in mysql_config
        raise EnvironmentError("%s not found" % (mysql_config.path,))
    EnvironmentError: mysql_config not found
    Complete output from command python setup.py egg_info:
    sh: mysql_config: command not found
 
Traceback (most recent call last):
 
  File "<string>", line 14, in <module>
 
  File "/Users/Max/.virtualenvs/zooscator/build/MySQL-python/setup.py", line 17, in <module>
 
    metadata, options = get_config()
 
  File "setup_posix.py", line 43, in get_config
 
    libs = mysql_config("libs_r")
 
  File "setup_posix.py", line 25, in mysql_config
 
    raise EnvironmentError("%s not found" % (mysql_config.path,))
 
EnvironmentError: mysql_config not found
 
----------------------------------------
Command python setup.py egg_info failed with error code 1
Storing complete log in /Users/Max/.pip/pip.log

Il faut éditer votre fichier activate qui se trouve dans le répertoire bin de votre environnement virtuel: ex “/Users/Max/.virtualenvs/zooscator/bin/activate”

vi /Users/Max/.virtualenvs/zooscator/bin

Trouvez les lignes suivantes et ajoutez:

PATH=”$PATH:/opt/local/lib/mysql5/bin/”

...
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
PATH="$PATH:/opt/local/lib/mysql5/bin/"
export PATH
...

Chez moi le chemin vers mysql est /opt/local/lib/mysql5/bin/, si vous ne connaissez pas le vôtre utilisez la commande locate: ex locate mysql

Une fois le fichier activate édité il faut le resourcer:

source /Users/Max/.virtualenvs/zooscator/bin/activate

Et vous pourrez alors installer MySQL-python tranquillou billou:

Max $  pip install MySQL-python
 
Downloading/unpacking MySQL-python
  Running setup.py egg_info for package MySQL-python
 
Installing collected packages: MySQL-python
  Running setup.py install for MySQL-python
[....................]
Successfully installed MySQL-python
Cleaning up...

Je vais nourir mon cochon d’Inde.

flattr this!

]]>
http://sametmax.com/virtualenv-environmenterror-mysql_config-not-found-sous-mac-osx/feed/ 14
ERROR: invalid locale name avec PostGres http://sametmax.com/error-invalid-locale-name-avec-postgres/ http://sametmax.com/error-invalid-locale-name-avec-postgres/#comments Thu, 30 Jan 2014 13:12:02 +0000 Sam http://sametmax.com/?p=8743 Il suffit de redémarrer PostGres.

Ca arrive quand on met à jour ses locales et que des services tournent. Ils ne reçoivent pas l’information, et utilisent l’ancienne locale.

Oui, j’avais besoin d’un poste bouche-trou.

flattr this!

]]>
http://sametmax.com/error-invalid-locale-name-avec-postgres/feed/ 8
Remplacer sed, awk, cut et Perl par Python (= orgasme pour sysadmin) http://sametmax.com/remplacer-sed-awk-cut-et-perl-par-python-orgasme-pour-sysadmin/ http://sametmax.com/remplacer-sed-awk-cut-et-perl-par-python-orgasme-pour-sysadmin/#comments Sat, 14 Dec 2013 08:28:41 +0000 Sam http://sametmax.com/?p=8261 La force de Perl c’est qu’il permettait de piper des données directement via la ligne de commande pour faire des manipulations rapides.

C’est pour cela que c’était devenu les choix des sysadmins. Parce que jusqu’ici, le choix c’était soit de faire un truc simple en connaissant par coeur la tool box GNU, soit ouvrir un fichier et faire un script.

Python ne permet pas de piper des données directement dans la commande, mais des projets ont vu le jour pour le faire.

Il y a le projet pyp, que l’on doit à Sony Pictures Imageworks qui avait besoin de se simplifier l’automatisation des tâches de build pour ses films.

Et il y a pyped, dont j’avais brièvement parlé ici (article qui mérite d’être mis à jour vu que j’ai remplace dateutils par arrow).

Les deux étaient sympas, mais avait des syntaxes alambiquées. Cependant, pyped est récemment passé en v1.0, donc stable, et a une toute nouvelle approche de syntaxe qui rend la bestiole super agréable à utiliser.

Présentation.

Stdin, ligne à ligne

L’installation est bateau, c’est du pip :

pip install --user pyped

Et derrirère, on obtient la commande py. Elle s’utilise essentiellement à la suite d’une autre commande. Typiquement :

cat /etc/fsta | py "un truc"

L’astuce, c’est que “un truc” peut être n’importe quelle expression Python. Généralement une expression qui print() quelque chose.

Or, Pyped met automatiquement à disposition de cette expression deux variables :

  • La ligne en cours, dans la variable x.
  • Le numéro de la ligne en cours, dans la variable i.

L’expression Python est appelée une fois pour chaque ligne.

Par exemple, supposons que j’ai un fichier “fortune.txt” contenant :

bitcoin (btc) : 5
euros () : 100
dollars ($) : 80

Si je veut tout mettre en majuscule, je fais :

$ cat fortune.txt | py "print(x.upper())"
BITCOIN (BTC) : 5
EUROS () : 100
DOLLARS ($) : 80

On peut mettre plusieurs expressions d’affilé. Ainsi, si je veux récupérer la somme et le symbole uniquement :

$ cat fortune.txt | py "devise, sign, _, value = x.split()" "sign = sign.strip('()')" "print('%s%s' % (value, sign))"
5btc
10080$

Ok, c’est plus long que perl, mais vachement plus facile à écrire et à relire. Et j’utilise un langage que je connais déjà. Et pas besoin de faire un mix incompréhensible de sed, awk et autre cut.

Si j’ai vraiment besoin de lisibilité, je peux même le mettre sur plusieurs lignes :

$ cat fortune.txt | py "                                                                                                 
devise, sign, _, value = x.split() 
sign = sign.strip('()') 
print('%s%s' % (value, sign))  
"
5btc
10080$

Vous aurez noté que j’utilise print() et que je semble ne pas me soucier de l’unicode. C’est parceque pyped fait ça au début du script :

from __future__ import print_function, unicode_literals, division, absolute_imports

Du coup, on est bien en Python 2.7, mais on bénéficie de la division améliorée, de la fonction pour printer, des imports absolus et surtout, de l’unicode partout. D’ailleurs pyped vous transforme x pour que ce soit un objet unicode.

Tout traiter d’un coup

Parfois, on a besoin d’avoir accès à toutes les lignes, pas juste les lignes une à une. pyped permet cela avec l’option -i. Les variables x et i disparaissent au profit de la variable l, qui contient un itérable sur toutes les lignes.

Par exemple, envie de trier tout ça ?

cat fortune.txt | py -i "
lignes = (x.split() for x in l)
lignes = sorted((v, s.strip('()')) for d, s, _, v in lignes)
for ligne in lignes: print('%s%s' % ligne)
"
100€
5btc
80$

Moar options

Lisez la doc, car il y a d’autres options du genre éviter que pyped vous strip automatiquement le ligne break, forcer l’encoding, etc.

Parmi les trucs les plus utiles, il y a l’option -b qui permet de lancer un code avant la boucle. Pratique pour importer des trucs genre le module tarfile pour extraire une archive avant d’utiliser son contenu.

Néanmoins la plupart du temps on a rien besoin d’importer car pyped importe déjà automatiquement les modules les plus utiles : maths, datetime, re, json, hashlib, uuid, etc.

flattr this!

]]>
http://sametmax.com/remplacer-sed-awk-cut-et-perl-par-python-orgasme-pour-sysadmin/feed/ 21
Introduction à Ansible: l’outil du sysadmin paresseux mais pragmatique http://sametmax.com/introduction-a-ansible-loutil-du-sysadmin-paresseux-mais-pragmatique/ http://sametmax.com/introduction-a-ansible-loutil-du-sysadmin-paresseux-mais-pragmatique/#comments Fri, 06 Dec 2013 10:43:19 +0000 VonTenia http://sametmax.com/?p=8177 Ceci est un post invité de VonTenia posté sous licence creative common 3.0 unported.

Je profite du fait que Sam & Max me donnent la parole pour vous parler d’Ansible, un programme très puissant et relativement simple dont je me sers depuis récemment (beaucoup trop tardivement à mon goût), mais qui a radicalement changé ma façon de gérer mes déploiements d’appli sur serveur.

Avant-propos : Ce guide s’adresse avant tout à ceux et celles ayant le minimum d’aisance avec les systèmes linux. Je pense qu’il est nécessaire de savoir marcher avant d’apprendre à courir, l’automatisation de configuration est une bonne chose (vous allez voir que vous ne pourrez plus vous en passer), mais si vous n’avez aucune idée de comment éditer un fichier de configuration, ou comment redémarrer un service, vous risqueriez bien d’être pris au dépourvu… Mieux vaut alors pour vous commencer par apprendre les bases de l’administration système puis revenir une fois à l’aise avec le concept.

Pourquoi utiliser un “Configuration Management Tool”

Vous vous dites : mon boulot c’est de coder, l’administration système c’est sympa 5 minutes mais ça me gonfle… Et pourtant, au final votre application sera accédée via vos serveurs, et selon leur fragilité, la satisfaction de vos clients pourrait en pâtir (ce malgré votre excellent code parfaitement testé).

En tant que dev, il serait risible pour vous de ne pas versionner votre code ou ne pas le tester. Pourtant c’est ce que vous faites avec vos systèmes en n’utilisant pas de CfM. Et personne n’est à l’abri des aléas de la vie, par exemple:

  • vous êtes hébergé dans le cloud et votre voisin d’hyperviseur s’avère maintenir un site Tor de trafic d’organes et de prostitution animalière (tout ça pour blanchir des bitcoins)… Vous apprécierez moyennement le downtime lorsque le FBI saisira le serveur que vous partagiez avec cet indélicat voisin.
  • Votre sysadmin ultra compètent pourrait se trouver dans l’incapacité d’exercer à la suite d’une banale auto-asphyxie érotique qui aurait mal tournée. Et bien évidemment il n’a rien documenté avant, le saligaud…

Bref, le genre de risque qu’on apprend à identifier quand on passe sa certif ITIL…

Les alternatives aux CfM

Je vous vois venir, me disant que vous ne m’avez pas attendu pour envisager les situations précédentes. Vous avez déjà un plan de secours, à savoir :

  • Des scripts : Si vous êtes déjà un peu plus malin que la moyenne, vous vous êtes aperçu que pour déployer une nouvelle machine, vous tapez toujours les mêmes commandes : installer vos packages, les configurer, démarrer les services. Vous aurez donc votre collection de scripts shell ou fabric pour vous aider à la tâche.

    Inconvénient : il faut être très organisé, gérer les différents fichiers de config peut prendre du temps lorsqu’il faut les modifier pour chaque serveur. Il est aussi parfois dangereux de relancer le script plusieurs fois sur la même machine, cela peut avoir des conséquences pour le moins hasardeuses.

  • Une image disque : Une fois votre serveur configuré et parfaitement fonctionnel, vous avez pris soin d’en prendre une image disque. Le saint Graal de la prod, contenant la vérité absolue. En cas de crash vous serez opérationnel en un rien de temps.

    Inconvénient : Les besoins de votre application vont évoluer avec le temps, les fichiers de configuration auront probablement changé aussi. A chaque changement vous devez refaire votre image… Ça devient assez lourd à la longue, et c’est facile d’oublier de le faire jusqu’au jour où “the shit hit the fan”.

  • Rien (ou presque) : Si vous êtes comme moi, d’un naturel optimiste, vous n’avez quasiment pas de solution de secours (à part des backups). Le jour ou votre serveur crash, vous essayez de fixer le problème, et au pire vous en re-configurez un nouveau, ce qui vous prends entre 2 heures et 2 jours, en fonction de la dernière fois où vous avez eu à le faire (je n’ai jamais prétendu être un sysadmin très compètent…). Sans aller jusqu’au crash irrécupérable, le simple fait de vouloir changer d’hébergeur peut vous faire perdre un temps précieux. Vous perdez donc en flexibilité.

    Inutile de vous dire que si vous faites parti de cette catégorie, je vous invite d’autant plus à continuer de lire.

Ansible à votre secours

Ansible est un outil open-source de gestion de configuration écrit en python (aussi dispo en version commerciale avec une interface graphique et un service de déploiement). La configuration se fait via des fichiers appelés “Playbooks”. Citons parmi les avantages :

  • Un système déclaratif : syntaxe YAML facilement lisible, ce qui rend l’apprentissage très rapide (plus qu’avec Chef à mon goût, où l’on s’empêtre très vite dans des problèmes de dépendance, et en plus je ne suis pas très fluent en ruby).
  • Templating des fichiers de configuration : qui permet d’avoir des fichiers dynamiquement générés en fonction de ce que vous voulez, tel que le rôle du serveur, ou bien dépendant d’un autre serveur. En plus le langage de template par défaut est Jinja2, ça plaira aux amateurs de Django.
  • Quasiment rien à installer. A part Ansible sur votre machine hôte, tout ce dont vous avez besoin c’est d’un accès root via SSH sur vos serveurs cibles.

Ansible ne sert pas qu’à déployer votre infrastructure, il peut aussi servir à tester et s’assurer que tous les services qui sont censés fonctionner soient bien tous actifs, et que tous les fichiers de configurations sont bien à jour. Autant vous dire que plus vous avez de machines, plus ça devient intéressant.

Je sens que j’écris beaucoup et que j’ai déjà perdu la moitié des lecteurs. Aussi je vous invite à suivre ce petit tutoriel que j’ai préparé rien que pour vous parce que vous êtes quand même sympa.

Tutoriel : Déployer une app django

Nous allons essayer de déployer l’application Django–an-app-at-a-time sur un système Debian wheezy en utilisant Ansible.

1. Préparer la machine cible

Pour les besoins du test, créer un serveur tout neuf sous Debian Wheezy :

  • Soit en utilisant Virtualbox (dans ce cas utilisez Debian netinstall). N’installez que le système de base et le serveur SSH. Seul impératif: un accès ssh via root sur la machine.
  • Si vous avez les moyens, vous pouvez aussi vous créer temporairement une machine cloud sur OVH ou digital ocean, ça pourrait être plus rapide.

2. Installer Ansible

Sur votre machine hôte (que j’assume être sous Ubuntu pour simplifier):

Installez Ansible, via pip (de façon globale sans passer par virtualenv) :
$ sudo pip install ansible

Générez clefs privée/publique si vous n’en avez pas déjà :
$ ssh-keygen

Copiez la clef publique sur le serveur cible (qui sera désigné par 192.168.1.1 dans ce tutoriel, mais bien entendu remplacez par l’adresse de votre serveur cible).
$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.1

Créez le fichier /etc/ansible/hosts qui contiendra la liste des serveurs à gérer, et placez-y l’adresse de votre serveur:
$ sudo vim /etc/ansible/hosts
192.168.1.1

Testez que le serveur soit bien accessible:
$ ansible all -m ping -u root
devrait retourner:
192.168.1.1 | success >> {
"changed": false,
"ping": "pong"
}

Bravo, Ansible est installé et peut communiquer avec votre serveur cible. En avant pour la magie !


3. Récupérer le Playbook de démo et l’exécuter

Clonez mon repo github concocté avec amour et exécutez le playbook:

$ git clone https://github.com/Remiz/playbook-demo.git
$ cd playbook-demo/
$ ansible-playbook site.yml

Maintenant, plus qu’à attendre…

3. Admirer le résultat

Visitez le site hébergé à l’adresse de votre serveur (dans mon exemple http://192.168.1.1)

Votre réaction la plus normale devrait être la suivante :

Je vous invite maintenant à ouvrir le playbook site.yml et essayer de comprendre. Durant ce court laps de temps, nous avons:

  • Créé un utilisateur “myproject”
  • Ajouté cet utilisateur aux sudoers
  • Ajouté votre clef privée locale
  • Mis a jour la date du serveur
  • Installé/activé le serveur NTP
  • Sécurisé le serveur en installant fail2ban et en configurant le firewall iptables (laissant ouvert les ports 22, 80, 443 et 4949 pour le monitoring sous munin)
  • Installé quelques outils systèmes bien utiles tel que git ou htop
  • Installé/configuré Nginx, Supervisor, Pip, virtualenv
  • Cloné le repo Django–an-app-at-a-time
  • Créé un virtualenv avec django/gunicorn
  • Configuré gunicorn pour être lancé via supervisor
  • et finalement deployé les fichiers statiques…

Pas mal en 5 minutes, non ? Maintenant si vous ne me croyez pas, je vous invite à vous connecter sur votre serveur

$ ssh myproject@192.168.1.1

et tester les commandes suivantes :

$ date
$ sudo iptables -L
$ ps -ef | grep fail2ban
$ ps -ef | grep gunicorn

Notez que je n’ai pas utilisé runserver de Django, tout est proprement déployé sur une stack gunicorn/supervisor/virtualenv, bref je me suis pas foutu de votre gueule. Le Playbook est à vous, c’est cadeau. J’espère qu’il vous servira comme base pour vos futurs déploiements, et si jamais vous vous rendez compte que vous gagnez un temps fou à l’utiliser, n’hésitez pas à me payer une pinte si vous êtes de passage au Canada.

Une autre expérience intéressante consiste à relancer l’exécution du playbook :

$ ansible-playbook site.yml

Tout devrait aller beaucoup plus vite, et à la place de “changed” après chaque instruction, vous devriez lire “ok”. Ce qui veut dire qu’un playbook est plus intelligent qu’un bête script, et ne se contente pas d’exécuter des instructions, Ansible va garantir quel tel service soit bien actif et qu’il utilise bien le dernier fichier de conf. Ce qui en fait l’outil parfait pour tester vos systèmes automatiquement.

La syntaxe Playbook

Le but de ce tutoriel n’est que de vous présenter Ansible, aussi je ne rentrerai pas trop dans les détails et je vous inviterai à vous rendre sur le site officiel pour une documentation plus complète.

Un playbook est avant tout composé de tâches :

- name: Texte qui décris votre tâche
module: option=value

Une tâche va donc appeler un module Ansible, dont la fonction peut être de copier un fichier, démarrer un service, clôner un repository… Il y en a vraiment beaucoup. Chaque module reçoit des paramètres tels que : un fichier de configuration source (sur votre machine hôte), un path de destination, un package apt à installer… Référez vous à la doc pour savoir quels paramètres sont acceptés.

Exemples :

- name: Démarrer fail2ban
service: name=fail2ban state=started enabled=true

va s’assurer que le service appelé fail2ban soit bien démarré (le démarrer si ce n’est pas le cas), mais aussi s’assurer qu’il soit bien présent au démarrage du système. Quand je vous disait que la syntaxe est très simple (même plus simple qu’avec des scripts shell).

Autre exemple:

- name: Configurer Nginx
template: src=templates/nginx.conf.j2
dest=/etc/nginx/sites-enabled/{{ user }}.conf
notify: restart nginx

se traduit par : récupérer le template de conf dans le répertoire local templates/ (le parser avec les bonnes valeurs), et placer le résultat dans le répertoire de conf de Nginx (en utilisant le nom d’utilisateur comme nom du fichier). Enfin redémarrer nginx via un handler (uniquement si le contenu du fichier de conf a changé).

Conclusion (et aller plus loin)

Je vous conseille de lire la documentation officielle, elle est plutôt bien faite, dites-vous que je ne connaissais pas du tout cet outil il y a deux semaines et je m’en sert désormais régulièrement (et je suis du genre slow-learner). Renseignez vous particulièrement sur les rôles que vous pouvez donner à vos serveurs, ce qui vous permet de diviser vos playbooks (frontend, cluster DB, worker celery…), et ce qui encourage aussi la réutilisation (par exemple j’ai toujours un rôle “common” qui inclus tout ce qui est nécessaire à l’ensemble de mes serveurs : utilisateur admin, sécurité, timezone…). Comme on n’apprend jamais aussi bien que par l’exemple, n’hésitez pas à vous inspirer des exemples issus de la doc (l’outil évolue vite et certains ne sont plus entièrement valides, mais c’est toujours bon à prendre).

Si vous voulez pousser l’automatisation jusqu’à l’extrême, il est aussi possible de configurer Ansible sur vos serveurs pour se connecter à un repo git, récupérer les playbooks et fichiers de conf appropriés et s’auto-configurer…

Voila, mon rôle s’arrête ici et libre à vous d’en apprendre plus. Au final j’espère avoir tenu ma promesse d’éclairer vos esprit sur les miracles de l’automatisation.

flattr this!

]]>
http://sametmax.com/introduction-a-ansible-loutil-du-sysadmin-paresseux-mais-pragmatique/feed/ 29
Marre des mots de passe pour push sur git ? http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/ http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/#comments Tue, 19 Nov 2013 08:36:34 +0000 Sam http://sametmax.com/?p=8013 Vous êtes dans une situation où vous ne pouvez pas utiliser uniquement une clé pour vous authentifier, et il faut taper votre putain de mot de passe à chaque push.

Ça sent le vécu n’est-ce pas ?

Mais bien entendu git vient avec une option bien cachée au fond de son fion pour adresser ce problème :

git config credential.helper 'cache --timeout=3600'

Et votre authentification sera gardée en mémoire pour une heure. Vous pouvez faire :

git config --global credential.helper 'cache --timeout=3600'

Pour l’étendre à tous les repos de votre machine.

flattr this!

]]>
http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/feed/ 12
You are deprecated http://sametmax.com/you-are-deprecated/ http://sametmax.com/you-are-deprecated/#comments Mon, 18 Nov 2013 08:20:47 +0000 Toniob http://sametmax.com/?p=7985 Ceci est un post invité de Toniob posté sous licence creative common 3.0 unported.

Oh oui, je sais ce que vous allez me dire, et vous avez parfaitement raison. Oui, il m’arrive d’être un peu obtus sur certaines choses, surtout quand il s’agit d’un domaine que je connais. Bref, aujourd’hui nous allons parler de ifconfig et de route.

Soyons clair tout de suite : arrêtez d’utiliser ces merdes, elles sont dépréciées depuis longtemps ! Je sais comment sont les informaticiens de manière générale, et les administrateurs systèmes en particulier. Il est difficile de changer leurs habitudes. Mais si on vous proposait Scarlett Johansson, vous resteriez fidèle à Régine ou Jonathan Rhys Meyers si vous aviez Mickey Rourke ? Je vois à vos yeux lubriques que vous m’avez saisi. Alors c’est parti.

- ifconfig ? - ouiiiii ** tum tum tum tum **

Les interfaces

Utilisez la commande ip, c’est un ordre. Elle remplacera avantageusement ifconfig. Dans la suite de ce billet, je mettrai des exemples de commandes avec ifconfig et leur équivalent avec ip. Commençons avec du simple, afficher la liste des interfaces disponibles :

# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:90:f5:ee:62:31
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interruption:20 Mémoire:f7e00000-f7e20000

lo        Link encap:Boucle locale
          inet adr:127.0.0.1  Masque:255.0.0.0
          adr inet6: ::1/128 Scope:Hôte
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:12 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          RX bytes:720 (720.0 B)  TX bytes:720 (720.0 B)
$ ip addr
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0:  mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:90:f5:ee:62:31 brd ff:ff:ff:ff:ff:ff

Vous voyez, pour le moment ce n’est pas si compliqué, vous économisez même de précieuses lettres. Vous constatez que la sortie est différente, mais vous y trouverez globalement les mêmes informations. C’est une question d’habitude. Personnellement, ça m’a pris un peu de temps, mais je ne reviendrais en arrière pour rien au monde.

On va maintenant assigner une adresse ip. Bon, j’avoue, c’est un peu plus long cette fois avec la commande ip :

# ifconfig eth0 192.168.1.1/24
# ip addr add 192.168.1.1/24 dev eth0

Et si maintenant nous ajoutions une adresse ipv4 ? Sauf qu’avec ifconfig, ce n’est pas possible, on ne peut le faire qu’avec ip :

# ip addr add 192.168.1.2/32 dev eth0

Si on affiche la configuration de l’interface réseau :

# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:90:f5:ee:62:31
          inet adr:192.168.1.1  Bcast:0.0.0.0  Masque:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interruption:20 Mémoire:f7e00000-f7e20000
$ ip addr show eth0
2: eth0:  mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether 00:90:f5:ee:62:31 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet 192.168.1.2/32 scope global eth0
       valid_lft forever preferred_lft forever

Et oui, rien du côté de ifconfig. Il ne voit pas que l’interface dispose de deux adresses différentes. Alors qu’il fallait utiliser des alias d’interface avec ifconfig, plus de souci de ce côté là avec ip. Voici maintenant quelques exemples d’autres commandes pouvant être utiles :

# ifconfig eth0 mtu 9000
# ip link set eth0 mtu 9000

# ifconfig eth0 up
# ip link set eth0 up

Les routes

Passons maintenant aux routes. Si vous utilisez ifconfig, vous vous servez aussi probablement de route. C’est fini les conneries maintenant ! Commençons par les afficher :

# route -n
Table de routage IP du noyau
Destination     Passerelle      Genmask         Indic Metric Ref    Use Iface
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
$ ip route
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.1

Oui, la sortie est moins verbeuse par défaut. Ça devrait vous plaire pour vos scripts shell. Ajoutons maintenant une route par défaut :

# route add default gw 192.168.1.254
# ip route add defaut via 192.168.1.254

Et si on regarde le résultat de la commande ip route maintenant :

$ ip route
default via 192.168.1.254 dev eth0
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.1

Contrairement à route, ip route génère une sortie qui peut être copiée / collée dans un ip route add. Pratique pour dupliquer une conf sur un autre serveur. Pour ajouter une route vers un hôte ou un réseau en particulier :

# route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.1.253
# ip route add 192.168.2.0/24 via 192.168.1.253

C’est une affaire de goût, mais je préfère largement la syntaxe de ip à celle de route.

Conclusion

Voilà cette petite introduction à la commande ip est terminée. Essayez de remplacer ifconfig dans vos usages au quotidien. Ça prend un peu de temps pour s’y faire, mais la syntaxe plus claire et les fonctionnalités disponibles permettent vite d’être plus rapide dans la configuration réseau d’une machine. Les exemples que j’ai donnés dans cet article devraient être suffisants pour 90% des usages. Si vous cherchez à vouloir en faire plus, il suffit d’ajouter l’option help à votre ligne de commande pour avoir des informations. Plus pratique que d’avoir à taper dans le man sans arrêt.

Si cet article vous plaît (merci de me faire des commentaires élogieux, c’est mon premier ici), j’essaierai de vous faire découvrir un peu plus la stack réseau sous Linux. Si les vlans sont connus, les bondings un peu moins, je pense que les macvtaps sont un mystère pour la plupart d’entre vous. Et tout se fait avec l’aide d’ip en plus, que demande le peuple ?

Et si la conf réseau ça vous saoule, je trouverai à m’énerver sur d’autres choses (le larousse n’a qu’à bien se tenir).

flattr this!

]]>
http://sametmax.com/you-are-deprecated/feed/ 18
Changer la timezone sous Ubuntu Server en ligne de commande http://sametmax.com/changer-la-timezone-sous-ubuntu-server-en-ligne-de-commande/ http://sametmax.com/changer-la-timezone-sous-ubuntu-server-en-ligne-de-commande/#comments Fri, 15 Nov 2013 10:28:15 +0000 Sam http://sametmax.com/?p=7954 toujours être UTC. Sous Ubuntu server, ça se fait en deux lignes. ]]> Avoir tous ses serveur à la même heure, c’est primordial. Et cette même heure devrait toujours être UTC.

Du coup dans votre script de déploiement, n’oubliez pas de changer la timezone de la machine.

Sous Ubuntu server, ça se fait en deux lignes :

echo "UTC" | sudo tee /etc/timezone
sudo dpkg-reconfigure  --frontend noninteractive  tzdata

Si vous avez des cron, redémarrez le daemon sinon il sera toujours décalé :

sudo service cron restart

Si vous êtes du genre à aimer la précision, vous pouvez installer un daemon NTP qui permet de synchroniser l’horloge du serveur régulièrement avec un serveur distant :

sudo apt-get -y install ntp

flattr this!

]]>
http://sametmax.com/changer-la-timezone-sous-ubuntu-server-en-ligne-de-commande/feed/ 0
La stack techno qu’on utilise pour faire un site Web, et pourquoi http://sametmax.com/la-stack-techno-quon-utilise-pour-faire-un-site-web-et-pourquoi/ http://sametmax.com/la-stack-techno-quon-utilise-pour-faire-un-site-web-et-pourquoi/#comments Mon, 11 Nov 2013 06:40:38 +0000 Sam http://sametmax.com/?p=7648 Une stack techno n’est pas une référence. Il n’y a pas de combo absolu qui rox absolument tout, c’est une question de contexte technique, financier, humain…

Mais c’est vrai que ça aide bien d’avoir sous les yeux les pratiques des autres.

Je ne vais pas expliquer pourquoi Python, je l’ai déjà fait.

Commençons plutôt par la partie purement Web, pour laquelle on utilise Django, le framework Web Python.

Max et moi avons tout deux fait du PHP avant, j’ai tâté des frameworks internes, du Symfony et plus tard du Zope. J’ai regardé du côté de Pyramid et de ses prédécesseurs, et Django est celui qui me plaît le plus. J’ai juste un peu forcé la main à Max :-)

Car oui, le framework a été avant tout un choix de goût.

Ce n’est pas un choix de performances : le framework n’a aucun impact dessus. Aucun. Les architectures ont un impact. Le framework, non. Votre bottleneck sera sur les IO, pas sur le CPU. Le choix de technos asynchrones peut avoir un impact, mais ce n’est pas une question de framework. Tornado, Twisted ou NodeJS, on s’en fout.

Donc Django, essentiellement parce qu’il me plait. Et il me plaît pour ces raisons :

  • Il y a un bon équilibre entre découplage et intégration. En général c’est soit très découplé et mal intégré, soit très bien intégré et très couplé.
  • C’est bien foutu et bien documenté. Et c’est stable. Vraiment très stable. Les core devs sont hyper sérieux.
  • C’est très versatile et ça peut faire plein de trucs out of the box, petits comme gros.
  • C’est assez facile à apprendre. Ça reste un framework, donc ce n’est pas la plus simple des démarches, mais dans le royaume des frameworks de cette taille, ça reste vraiment le plus simple.
  • La communauté est fantastique : il y a des centaines d’apps qui couvrent pratiquement tous les besoins.
  • Et bien entendu, c’est en Python.

En terme de base de données, on a fait du MySQL pendant longtemps. Ça a plutôt bien marché. Maintenant je commence mes nouveaux projets avec PostGres, qui est plus solide. Parfois je fais juste du Sqlite, parce que ça suffit.

Pas de NoSQL. Après plusieurs expériences avec MongoDB et CouchDB, je n’ai pas été convaincu que les bénéfices dépassaient le coût. Il faudrait un article complet là dessus (qu’on m’a d’ailleurs demandé).

Question OS. c’est du CentOS avec Max (il a plus l’habitude) ou du Ubuntu Server pour mes autres projets. Je reste sur les LTS. Ce n’est pas un choix très réfléchi, c’est surtout par habitude.

Pas de machine virtuelle. On a essayé, sans y trouver un grand intérêt :

  • Il faut quand même faire des scripts de migration, donc autant s’en servir pour le déploiement.
  • On perd en perfs.
  • Les erreurs liées au mal-fonctionnement d’une VM sont absolument indébuggable.
  • Si on ne fait pas la VM soit-même, il faut mettre ses couilles dans les mains d’un pestataire de service. J’ai horreur de ça.
  • Trouver des gens avec la compétence pour gérer une VM, c’est difficile. Un script de déploiement, c’est du code que tout dev saura déjà lire. Par extension ça veut dire que je m’y replonge facilement des semaines plus tard.

Et donc pour le déploiement, j’utilise fabric, avec fabtools.

Ce n’est pas la solution la plus efficace, d’autant que ça limite à Python 2.7, mais c’est la plus simple. C’est juste du code Python. N’importe qui peut comprendre le déploiement en 15 minutes. Ça se modifie vite, s’adapte facilement.

Il faut comprendre qu’on a jamais plus d’une dizaine de serveurs pour un projet, ces choix sont donc fait en fonction de cela. Il va sans dire que si vous gérez un parc de centaines de machines, ça ne sera pas du tout le même choix technique. Peut être que Chef ou des VM seront alors carrément plus interressant. Peut être que le NoSQL et sa capacité au scalling sera bien plus rentable.

Il ne s’agit pas de décrier les technos que nous n’utilisons pas. Il s’agit juste de dire, voilà les choix que nous avons fait, dans tel contexte, pour telles (bonnes ou mauvaises) raisons.

Durant les dernières années, on a ajouté Redis à notre stack. C’est un outil fantastique qui sert à tout : de la base de données pour les trucs simples (il y a des fois ou un schéma est overkill) à la solution de caching. C’est ce qu’on a de plus proche du NoSQL.

L’outil est tellement simple à installer (vraiment le degré zero de la maintenance, c’est beau) et à utiliser que ça ne vaut juste pas le coup de s’en priver.

Du coup, plus de memcache. Toutes les grosses requêtes sont sauvegardées dans Redis, dès qu’on fait un script qui a besoin de persistance temporaire, Redis, pour communiquer entre plusieurs process, Redis, pour toutes les opérations qui ont besoin de grosses perfs comme les stats, Redis. Vive Redis.

D’ailleurs on utilise Redis aussi comme broker pour notre gestionnaire de queues et de taches : celery. Si vous pythonez, je vous recommande chaudement celery pour toutes les tâches en background, les crawlers, les chaînes de process, etc.

On a aussi du moteur de recherche. Là on tappe dans du Solr (avec haystack). C’est très puissant, en tout cas syntaxiquement car ça ne fait pas de sémantique. Ne vous attendez-donc pas à rattraper Google. Mais c’est aussi méga chiant à configurer et très lourd. Je pense qu’un jour on va migrer sur ElasticSearch, mais c’est pas la priorité. Don’t fix what ain’t broken.

Devant tout ça on a Nginx. Comme beaucoup on a fait Apache => Cherokee => lighttp => nginx. Et franchement, je ne reviendrais jamais en arrière : plus léger, plus rapide, plus facile à installer et à configurer, plus versatile. Nginx fait tout, et mieux.

En proxy on a du gunicorn. Parce qu’on avait la flemme de configurer uwsgi et qu’on a pris l’habitude.

Après on utilise plein de libs, de petits outils, etc. Mais ça c’est le gros de notre archi.

flattr this!

]]>
http://sametmax.com/la-stack-techno-quon-utilise-pour-faire-un-site-web-et-pourquoi/feed/ 25
WARNING: File not found. Did you forget to save? http://sametmax.com/warning-file-not-found-did-you-forget-to-save/ http://sametmax.com/warning-file-not-found-did-you-forget-to-save/#comments Sat, 26 Oct 2013 07:58:23 +0000 Sam http://sametmax.com/?p=7541 rapporter ce problème quand il utilisait la commande magique %edit dans IPython avec Sublime Text.]]> Un lecteur nous a rapporté ce problème quand il utilisait la commande magique %edit dans IPython avec Sublime Text.

Magie d’internet, un autre lecteur lui a répondu en comment, mais je me dis que donner un peu de visibilité à la réponse peut pas faire de mal, vu que je n’ai pas trouvé facilement la solution via Google DuckDuckGo.

L’idée est tout simplement d’utiliser l’option -w dans la ligne de commande pour appeler l’éditeur. En effet, sans cela l’appel à ST est non bloquant, et IPython perd la référence au processus sans avoir de valeur de retour.

Par exemple, dans votre ipython_config.py :

c.TerminalInteractiveShell.editor = "sublime_text -w"

flattr this!

]]>
http://sametmax.com/warning-file-not-found-did-you-forget-to-save/feed/ 1
Afficher l’IP d’un visiteur – Django vs Nginx http://sametmax.com/afficher-la-vrai-ip-dun-visiteur-django-vs-nginx/ http://sametmax.com/afficher-la-vrai-ip-dun-visiteur-django-vs-nginx/#comments Fri, 25 Oct 2013 03:53:30 +0000 Max http://sametmax.com/?p=7525 Lorsque l’on veut connaitre son ip on fait souvent appel à des sites du genre: whatismyip.com, mon-ip.com ou on utilise un ifconfig en ssh.
Des fois on a aussi besoin de connaître l’ip d’un visiteur sur son site, 2 petites méthodes pour le faire sous Django et Nginx.

Sous Django:

Dans l’Urlconf

urlpatterns = patterns('',
    # return client IP
    url(r'^my_ip$', get_ip),
)

Créez une vue du nom de get_ip qui sera utilisée par l’urlconf

from django import http
 
def get_ip(request):
    """
        Vue qui retourne l'IP du client
    """
    try:
 
    	# récupère l'ip du client
        return http.HttpResponse(request.META["REMOTE_ADDR"] )
 
    except Exception, e:
        return http.HttpResponse('error %s' % e)

Le code ci-dessus peut retourner l’adresse locale (127.0.0.1) dans ce cas il faut tester l’existence de la variable HTTP_X_REAL_IP, certains serveurs web ont besoin d’être configuré.

Sous Nginx:

Dans le fichier de configuration de nginx on écrit une nouvelle location

# return client ip
location /my_ip {
    default_type 'text/plain';
    content_by_lua 'ngx.print(ngx.var.remote_addr)';
}

il suffit de se rendre à l’url http://monsite.com/my_ip pour voir s’afficher son ip. Cependant il faut avoir nginx compilé avec le module Lua ce qui peut être délicat si l’on a jamais compilé d’application.


Conclusion:

Si l’on s’en réfère aux deux exemples ci dessus on serait tenté d’utiliser Nginx car en une seule ligne tout le bazar est réglé.
Le hic c’est qu’il faut que Nginx soit compilé avec le module Lua pour afficher l’ip (sauf si quelqu’un connaît une autre façon d’afficher un message de sortie).
La version Django n’est pas fiable à 100% car suivant comment est configuré votre serveur web il se peut que vous vous retrouviez avec une ip du genre 127.0.0.1.
Il y a aussi la possibilité de parser le résultat des sites web cités en tout début d’article, certains proposent des Api je crois mais vous dépendez d’un autre service (on faisait ça au début) qui peuvent vous lâcher à tout moment (ce qui nous est arrivé).
Personnellement je compile toujours nginx avec Lua et quelques autres modules, ça permet de s’affranchir de plus en plus du backend.

PS: j’ai mis à jour le titre car il laissait sous-entendre autre chose (merci à Sébastien)

flattr this!

]]>
http://sametmax.com/afficher-la-vrai-ip-dun-visiteur-django-vs-nginx/feed/ 11