Le projet "auf-referentiels" devient "auf-refer", comprend qui peut... ;-)
authorProgfou <jean-christophe.andre@auf.org>
Wed, 15 Jul 2009 21:59:35 +0000 (04:59 +0700)
committerProgfou <jean-christophe.andre@auf.org>
Wed, 15 Jul 2009 22:10:35 +0000 (05:10 +0700)
17 files changed:
Makefile [new file with mode: 0644]
README [new file with mode: 0644]
apache.conf [new file with mode: 0644]
auf-refer [new file with mode: 0755]
auf-refer.conf [new file with mode: 0644]
debian/auf-refer.8 [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/cron.d [new file with mode: 0644]
debian/dirs [new file with mode: 0644]
debian/lintian-overrides [new file with mode: 0644]
debian/manpages [new file with mode: 0644]
debian/postinst [new file with mode: 0644]
debian/postrm [new file with mode: 0644]
debian/rules [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..fd55e72
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+VERSION = $(shell dpkg-parsechangelog | sed -n 's/^Version: //p')
+DIST = $(shell dpkg-parsechangelog | sed -n 's/^Distribution: //p')
+
+all: build
+
+build:
+
+install:
+       install -m 0755 -d $(DESTDIR)/usr/sbin
+       install -m 0755 auf-refer $(DESTDIR)/usr/sbin/
+       install -m 0755 -d $(DESTDIR)/etc/auf-refer
+       install -m 0644 *.conf $(DESTDIR)/etc/auf-refer/
+       install -m 0755 -d $(DESTDIR)/var/lib/auf-refer
+
+clean:
+
+test:
+       debuild -I.git -I*.ex -b -us -uc && sudo debi
+
+release:
+       debuild -I.git -I*.ex -tc && debrelease --dput $(DIST)-test
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..78ee23c
--- /dev/null
+++ b/README
@@ -0,0 +1,17 @@
+Pré-requis : avoir accès à un site web servant les référentiels AuF.
+Par défaut il faut avoir accès à http://intranet.auf/ et donc au RPV.
+Mais ce paquet peut aussi servir à mettre en place un tel site web.
+
+Ce paquet effectuera une copie puis une mise à jour automatique des
+référentiels AuF sélectionnés.
+
+La sélection des référentiels se fait avec la commande "auf-refer".
+La copie sera déposée dans "/var/lib/auf-refer/" au format JSON.
+
+La mise à jour sera effectuée automatiquement chaque jour à 7h et à 13h.
+On peut aussi la forcer manuellement avec "sudo auf-refer -u".
+
+Le processus de mise à jour est optimisé pour ne faire un téléchargement
+que s'il y a eu des changements depuis le téléchargement précédent.
+
+ -- Progfou <jean-christophe.andre@auf.org>  Thu, 16 Jul 2009 04:40:39 +0700
diff --git a/apache.conf b/apache.conf
new file mode 100644 (file)
index 0000000..79e299e
--- /dev/null
@@ -0,0 +1,12 @@
+Alias /auf-refer/ /var/lib/auf-refer/
+<Location /auf-refer>
+  Order deny,allow
+  Deny from All
+  Allow from 127.0.0.0/255.0.0.0
+  Allow from 10.0.0.0/255.0.0.0
+  Options Indexes
+  <IfModule mod_mime.c>
+    AddType application/json .json
+    AddCharset UTF-8 .json
+  </IfModule>
+</Location>
diff --git a/auf-refer b/auf-refer
new file mode 100755 (executable)
index 0000000..41a9eb1
--- /dev/null
+++ b/auf-refer
@@ -0,0 +1,228 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""Copie et mise à jour des référentiels AuF.
+
+Copyright ©2009  Agence universitaire de la Francophonie
+Licence : GPL version 3
+Auteur : Progfou <jean-christophe.andre@auf.org>
+
+Dépendances Debian : python >= 2.5, python-simplejson
+"""
+
+PROG_NAME = 'auf-refer'
+RUN_USER = 'auf-refer'
+DIR_BASE = '/var/lib/auf-refer/'
+URL_BASE = 'http://intranet.auf/auf-refer/'
+
+f = file('/etc/auf-refer/auf-refer.conf')
+lines = filter(lambda l: not l.startswith('#'), f.readlines())
+config = dict(map(lambda l: map(lambda s: s.strip(), l.split('=')), lines))
+
+URL_BASE = config.get('URL_BASE', URL_BASE).rstrip('/') + '/'
+
+__all__ = ( 'RUN_USER', 'DIR_BASE', 'URL_BASE' )
+
+USAGE = """Usages (à lancer en tant que "root", par exemple via "sudo") :
+  auf-refer [-f] -a <ref> - copie un nouveau référentiel
+  auf-refer -d <ref>      - supprime un référentiel
+  auf-refer [-f] -u       - met à jour les référentiels
+  auf-refer -l            - liste les référentiels copiés
+  auf-refer -L            - liste les référentiels disponibles
+  auf-refer [-f] -A       - copie tous les référentiels disponibles
+
+L'option -f permet de forcer le rechargement à travers un proxy/cache.
+"""
+
+TIME_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
+
+from sys import argv, exit, stderr
+from getopt import getopt, GetoptError
+from pwd import getpwnam
+from os import getuid, setgid, setuid, listdir, utime, unlink
+from os.path import join, exists, getmtime
+from time import gmtime, strftime
+from calendar import timegm
+from urllib2 import Request, urlopen, HTTPError, URLError
+from cStringIO import StringIO
+from gzip import GzipFile
+from simplejson import loads
+
+def update_referentiel(referentiel, force=False):
+    headers = {}
+    headers['Accept-Encoding'] = 'x-gzip'
+    if force:
+        headers['Pragma'] = 'no-cache'
+    filename = join(DIR_BASE, referentiel)
+    if exists(filename):
+        # n'effectuer le chargement qu'en cas de nouvelle version
+        mtime = gmtime(getmtime(filename))
+        headers['If-Modified-Since'] = strftime(TIME_FORMAT, mtime)
+    else:
+        # fichier vide à date très ancienne pour déclencher la synchro
+        try:
+            switch_user()
+            file(filename, 'a').close()
+        except IOError, msg:
+            raise RuntimeError, \
+                u"La création du référentiel a été refusée : %s" % msg
+        utime(filename, (0, 0))
+    url = URL_BASE + referentiel
+    req = Request(url, None, headers)
+    try:
+        u = urlopen(req)
+    except HTTPError, e:
+        if e.code == 304:
+            return
+        raise RuntimeError, \
+            u"L'URL suivante renvoie un code d'erreur %s :\n  %s" \
+                                                        % (e.code, url)
+    except URLError:
+        raise RuntimeError, u"L'URL suivante est inaccessible :\n  %s" % url
+    i = u.info()
+    if referentiel.endswith('.json') and i.type != 'application/json':
+        u.close()
+        raise RuntimeError, \
+            u"Le type des données chargées n'est pas JSON mais '%s'." % i.type
+    data = u.read()
+    if i.get('content-encoding') == 'x-gzip':
+        data = GzipFile('', 'r', 0, StringIO(data)).read()
+    u.close()
+    if referentiel.endswith('.json'):
+        try:
+            loads(data, encoding='utf-8')
+        except ValueError:
+            raise RuntimeError, u"Les données ne sont pas au format JSON."
+    # si on est arrivé jusqu'ici c'est que tout va bien... on enregistre !
+    try:
+        switch_user()
+        f = file(filename, 'wb')
+    except IOError, msg:
+        raise RuntimeError, \
+            u"L'écriture du référentiel a été refusée : %s" % msg
+    f.write(data)
+    f.close()
+    # on fixe la date donnée par le serveur, le cas échéant
+    mtime = i.getdate('last-modified')
+    if mtime:
+        mtime = timegm(mtime)
+        utime(filename, (mtime, mtime))
+
+def add_referentiel(referentiel, force=False):
+    if referentiel in listdir(DIR_BASE):
+        raise RuntimeError, \
+            u"Le référentiel '%s' avait déjà été ajouté." % referentiel
+    update_referentiel(referentiel, force)
+
+def delete_referentiel(referentiel):
+    if not referentiel in listdir(DIR_BASE):
+        raise RuntimeError, u"Le référentiel '%s' est absent." % referentiel
+    try:
+        switch_user()
+        unlink(join(DIR_BASE, referentiel))
+    except IOError, msg:
+        raise RuntimeError, \
+            u"La suppression du référentiel '%s' a été refusée :\n  %s" \
+                                                    % (referentiel, msg)
+
+def update_referentiels(force=False):
+    error_messages = []
+    for referentiel in listdir(DIR_BASE):
+        try:
+            update_referentiel(referentiel, force)
+        except Exception, msg:
+            error_messages.append(unicode(msg))
+    if error_messages:
+        raise RuntimeError, u'\n'.join(error_messages)
+
+def list_referentiels():
+    for referentiel in listdir(DIR_BASE):
+        print referentiel
+
+def get_referentiels_available(force=False):
+    referentiel = 'auf-refer.json'
+    filename = join(DIR_BASE, referentiel)
+    if not exists(filename):
+        update_referentiel(referentiel, force)
+    try:
+        f = open(filename, 'rb')
+    except IOError:
+        raise RuntimeError, u"La liste des référentiels est indisponible."
+    try:
+        referentiels = loads(f.read(), encoding='utf-8')
+    except ValueError:
+        raise RuntimeError, \
+            u"La liste des référentiels n'est pas au format JSON.\n" \
+            u"Essayez les options -f et -u pour la mettre à jour."
+    f.close()
+    return referentiels
+
+def list_referentiels_available(force=False):
+    referentiels = get_referentiels_available(force)
+    for referentiel in sorted(referentiels):
+        print "%-16s : %s" % (referentiel, referentiels[referentiel])
+
+def add_referentiels_available(force=False):
+    referentiels = get_referentiels_available(force)
+    referentiels = set(referentiels) - set(listdir(DIR_BASE))
+    for referentiel in referentiels:
+        update_referentiel(referentiel, force)
+
+_user_switched = False
+def switch_user(username=RUN_USER):
+    global _user_switched
+    if _user_switched:
+        return
+    try:
+        pw = getpwnam(username)
+    except KeyError:
+        raise RuntimeError, u"L'utilisateur '%s' n'existe pas." % username
+    try:
+        setgid(pw.pw_gid)
+        setuid(pw.pw_uid)
+    except OSError:
+        raise RuntimeError, \
+            u"Impossible de basculer vers l'utilisateur '%s'.\n" \
+            u"Réessayez avec 'sudo' !" % username
+    _user_switched = True
+
+if __name__ == '__main__':
+    # interdiction formelle de tourner sous 'root'
+    if getuid() == 0:
+        switch_user()
+
+    try:
+        opts, args = getopt(argv[1:], 'hfa:d:ulLA', ['help', 'force',
+            'add=', 'delete=', 'update', 'list',
+            'list-available', 'add-available'])
+    except GetoptError:
+        print USAGE
+        exit(1)
+
+    force = False
+    for opt, arg in opts:
+        if opt in ('-h', '--help'):
+            print USAGE
+            exit(0)
+        elif opt in ('-f', '--force'):
+            force = True
+        else:
+            try:
+                if opt in ('-a', '--add'):
+                    add_referentiel(arg, force=force)
+                elif opt in ('-d', '--delete'):
+                    delete_referentiel(arg)
+                elif opt in ('-u', '--update'):
+                    update_referentiels(force=force)
+                elif opt in ('-l', '--list'):
+                    list_referentiels()
+                elif opt in ('-L', '--list-available'):
+                    list_referentiels_available(force=force)
+                elif opt in ('-A', '--add-available'):
+                    add_referentiels_available(force=force)
+            except RuntimeError, msg:
+                print >>stderr, u'%s' % msg
+
+    if not opts:
+        print USAGE
+    exit(0)
+
diff --git a/auf-refer.conf b/auf-refer.conf
new file mode 100644 (file)
index 0000000..d617e8d
--- /dev/null
@@ -0,0 +1 @@
+URL_BASE=http://intranet.auf/auf-refer
diff --git a/debian/auf-refer.8 b/debian/auf-refer.8
new file mode 100644 (file)
index 0000000..4e2ee3c
--- /dev/null
@@ -0,0 +1,63 @@
+.TH AUF-REFER 8 "25 juin 2009"
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+auf-refer \- outil de copie et mise à jour des réferentiels AuF
+.SH SYNOPSIS
+\fBauf-refer\fP [\fB-f\fP] \fB-a\fP \fIreferentiel\fP
+.br
+\fBauf-refer\fP \fB-d\fP \fIreferentiel\fP
+.br
+\fBauf-refer\fP \fB-h\fP | \fB-l\fP
+.br
+\fBauf-refer\fP [\fB-f\fP] \fB-u\fP | \fB-L\fP | \fB-A\fP
+.SH DESCRIPTION
+Cette page de manuel documente brièvement la commande \fBauf-refer\fP.
+.PP
+.SH OPTIONS
+Ce programme suit la syntaxe habituelle d'une ligne de commande GNU,
+avec des options longues commençant par deux tirets (`-').
+.TP
+.B \-h, \-\-help
+Montre un résumé des options.
+.TP
+.B \-L, \-\-list-available
+Liste les référentiels disponibles. Cette liste est obtenue depuis un référentiel spécial nommé \fBauf-refer.json\fP. L'option \fB-f\fP permet de forcer le chargement à travers un proxy/cache.
+.TP
+.B \-A, \-\-add-available
+Copie tous les référentiels disponibles. Il seront ensuite mis à jour, soit automatiquement à 7h et 13h (en heure locale), soit manuellement avec l'option \fB-u\fP. L'option \fB-f\fP permet de forcer le chargement à travers un proxy/cache.
+.TP
+.B \-a, \-\-add
+Copie un nouveau référentiel. Il sera ensuite mis à jour, soit automatiquement à 7h et 13h (en heure locale), soit manuellement avec l'option \fB-u\fP. L'option \fB-f\fP permet de forcer le chargement à travers un proxy/cache.
+.TP
+.B \-l, \-\-list
+Liste les référentiel copiés.
+.TP
+.B \-u, \-\-update
+Met à jour les référentiels immédiatement. L'option \fB-f\fP permet de forcer le chargement à travers un proxy/cache.
+.TP
+.B \-d, \-\-delete
+Supprime un référentiel.
+.SH FILES
+.TP
+.B /etc/auf-refer/auf-refer.conf
+Fichier de configuration de cet outil.
+.br
+On y trouvera en particulier l'option suivante :
+.TP
+.B URL_BASE
+URL de base pour la copie des référentiels. Par défaut cette URL est positionnée sur \fBhttp://intranet.auf/auf-refer\fP.
+.SH AUTHOR
+L'outil auf-refer a été écrit par Progfou <jean-christophe.andre@auf.org>.
+.PP
+Cette page de manuel a été écrite par Progfou <jean-christophe.andre@auf.org>,
+pour le projet Debian (mais peut être utilisé par d'autres).
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..440b3a8
--- /dev/null
@@ -0,0 +1,41 @@
+auf-refer (0.5) jaunty; urgency=low
+
+  * Le projet "auf-referentiels" devient "auf-refer", comprend qui peut... ;-)
+
+ -- Progfou <jean-christophe.andre@auf.org>  Thu, 16 Jul 2009 05:08:44 +0700
+
+auf-refer (0.4) jaunty; urgency=low
+
+  * On n'impose plus la configuration Apache (sur remarque de Thomas).
+  * Suppression de la configuration via debconf (sur remarque de Thomas).
+  * Documentation du fichier de configuration dans la page de manuel.
+  * Nettoyage (effectif) des copies de référentiels en cas de purge.
+
+ -- Progfou <jean-christophe.andre@auf.org>  Thu, 25 Jun 2009 15:44:01 +0700
+
+auf-refer (0.3) jaunty; urgency=low
+
+  * Reformulation de quelques messages d'erreurs.
+  * Meilleur support des erreurs sur la liste des référentiels.
+  * Ajout des informations MIME pour JSON dans la configuration Apache.
+  * Ajout d'une option -A pour copier tous les référentiels d'un coup.
+
+ -- Progfou <jean-christophe.andre@auf.org>  Thu, 25 Jun 2009 14:38:36 +0700
+
+auf-refer (0.2) jaunty; urgency=low
+
+  * Utilisation d'un compte (et groupe) dédié : auf-refer
+  * Création de postinst/postrm et adaptation du cron.d en conséquence.
+  * Ajout du choix de l'URL de base via debconf et changement de la
+    valeur par défaut pour http://intranet.auf/auf-refer/
+  * Installation d'un fichier de configuration pour Apache 2.x.
+  * Création d'une page de manuel et mise à jour du README.
+
+ -- Progfou <jean-christophe.andre@auf.org>  Thu, 25 Jun 2009 09:51:44 +0700
+
+auf-refer (0.1) jaunty; urgency=low
+
+  * L'outil est fonctionnel, allons-y pour un empaquetage Debian.
+
+ -- Progfou <jean-christophe.andre@auf.org>  Tue, 23 Jun 2009 12:41:52 +0700
+
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..3c5cbad
--- /dev/null
@@ -0,0 +1,17 @@
+Source: auf-refer
+Section: auf
+Priority: optional
+Maintainer: Progfou <jean-christophe.andre@auf.org>
+Build-Depends: cdbs, debhelper (>= 5.0.0)
+Standards-Version: 3.7.3
+Homepage: http://git.auf.org/?p=auf-poste-client;a=tree;f=auf-refer
+
+Package: auf-refer
+Architecture: all
+Depends: ${misc:Depends}, adduser, python (>= 2.5), python-simplejson
+Provides: auf-referentiels
+Replaces: auf-referentiels
+Conflicts: auf-referentiels
+Description: outil de copie et mise à jour des réferentiels AuF
+ Ce paquet fournit un outil permettant de copier puis de mettre régulièrement
+ à jour une sélection des référentiels AuF.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..e1a2d27
--- /dev/null
@@ -0,0 +1,36 @@
+This package was debianized by Progfou <jean-christophe.andre@auf.org> on
+Tue, 23 Jun 2009 12:59:04 +0700
+
+It was downloaded from http://git.auf.org/ (projet auf-poste-client)
+
+Upstream Author:
+
+    Progfou <jean-christophe.andre@auf.org>
+
+Copyright Holder:
+
+    Copyright (C) 2009  Agence universitaire de la Francophonie
+                        http://www.auf.org/
+
+License:
+
+    This package is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This package is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this package; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
+The Debian packaging is (C) 2009, Progfou <jean-christophe.andre@auf.org> and
+is licensed under the GPL, see above.
+
diff --git a/debian/cron.d b/debian/cron.d
new file mode 100644 (file)
index 0000000..783c3a7
--- /dev/null
@@ -0,0 +1 @@
+0 7,13 * * *   auf-refer       [ -x /usr/sbin/auf-refer ] && /usr/sbin/auf-refer -u
diff --git a/debian/dirs b/debian/dirs
new file mode 100644 (file)
index 0000000..b34c28e
--- /dev/null
@@ -0,0 +1,3 @@
+usr/sbin
+etc/auf-refer
+var/lib/auf-refer
diff --git a/debian/lintian-overrides b/debian/lintian-overrides
new file mode 100644 (file)
index 0000000..1912100
--- /dev/null
@@ -0,0 +1,3 @@
+auf-refer source: maintainer-not-full-name Progfou
+auf-refer: maintainer-not-full-name Progfou
+auf-refer: unknown-section auf
diff --git a/debian/manpages b/debian/manpages
new file mode 100644 (file)
index 0000000..5a64f3f
--- /dev/null
@@ -0,0 +1 @@
+debian/auf-refer.8
diff --git a/debian/postinst b/debian/postinst
new file mode 100644 (file)
index 0000000..a1dfe59
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+set -e
+
+if getent passwd auf-referentiels >/dev/null ; then
+  deluser --quiet --system auf-referentiels
+  delgroup --quiet --system auf-referentiels
+fi
+
+if [ -d /usr/share/auf-referentiels ] ; then
+  mv /usr/share/auf-referentiels /var/lib/auf-refer
+fi
+
+if ! getent passwd auf-refer >/dev/null ; then
+  adduser --disabled-password --quiet --system \
+    --home /var/lib/auf-refer --no-create-home \
+    --group auf-refer
+fi
+
+if [ -d /var/lib/auf-refer ] ; then
+  chown -R auf-refer:auf-refer /var/lib/auf-refer
+  chmod 0755 /var/lib/auf-refer
+fi
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/postrm b/debian/postrm
new file mode 100644 (file)
index 0000000..e8009c0
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+#DEBHELPER#
+
+if [ "$1" = "purge" ] ; then
+  rm -rf /var/lib/auf-refer
+  deluser --quiet --system auf-refer
+  delgroup --quiet --system auf-refer
+fi
+
+exit 0
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..b2e6ff1
--- /dev/null
@@ -0,0 +1,6 @@
+#!/usr/bin/make -f
+
+DEB_MAKE_INSTALL_TARGET=install DESTDIR=$(DEB_DESTDIR)
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/makefile.mk
+include /usr/share/cdbs/1/rules/utils.mk