From 167a10d9266839428b2fc134cdb2d495e23ac2aa Mon Sep 17 00:00:00 2001 From: Progfou Date: Thu, 16 Jul 2009 04:59:35 +0700 Subject: [PATCH] Le projet "auf-referentiels" devient "auf-refer", comprend qui peut... ;-) --- Makefile | 22 +++++ README | 17 ++++ apache.conf | 12 +++ auf-refer | 228 ++++++++++++++++++++++++++++++++++++++++++++++ auf-refer.conf | 1 + debian/auf-refer.8 | 63 +++++++++++++ debian/changelog | 41 +++++++++ debian/compat | 1 + debian/control | 17 ++++ debian/copyright | 36 ++++++++ debian/cron.d | 1 + debian/dirs | 3 + debian/lintian-overrides | 3 + debian/manpages | 1 + debian/postinst | 27 ++++++ debian/postrm | 13 +++ debian/rules | 6 ++ 17 files changed, 492 insertions(+) create mode 100644 Makefile create mode 100644 README create mode 100644 apache.conf create mode 100755 auf-refer create mode 100644 auf-refer.conf create mode 100644 debian/auf-refer.8 create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/cron.d create mode 100644 debian/dirs create mode 100644 debian/lintian-overrides create mode 100644 debian/manpages create mode 100644 debian/postinst create mode 100644 debian/postrm create mode 100755 debian/rules diff --git a/Makefile b/Makefile new file mode 100644 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 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 Thu, 16 Jul 2009 04:40:39 +0700 diff --git a/apache.conf b/apache.conf new file mode 100644 index 0000000..79e299e --- /dev/null +++ b/apache.conf @@ -0,0 +1,12 @@ +Alias /auf-refer/ /var/lib/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 + + AddType application/json .json + AddCharset UTF-8 .json + + diff --git a/auf-refer b/auf-refer new file mode 100755 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 + +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 - copie un nouveau référentiel + auf-refer -d - 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 index 0000000..d617e8d --- /dev/null +++ b/auf-refer.conf @@ -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 index 0000000..4e2ee3c --- /dev/null +++ b/debian/auf-refer.8 @@ -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 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 . +.PP +Cette page de manuel a été écrite par Progfou , +pour le projet Debian (mais peut être utilisé par d'autres). diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..440b3a8 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,41 @@ +auf-refer (0.5) jaunty; urgency=low + + * Le projet "auf-referentiels" devient "auf-refer", comprend qui peut... ;-) + + -- Progfou 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 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 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 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 Tue, 23 Jun 2009 12:41:52 +0700 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..3c5cbad --- /dev/null +++ b/debian/control @@ -0,0 +1,17 @@ +Source: auf-refer +Section: auf +Priority: optional +Maintainer: Progfou +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 index 0000000..e1a2d27 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,36 @@ +This package was debianized by Progfou on +Tue, 23 Jun 2009 12:59:04 +0700 + +It was downloaded from http://git.auf.org/ (projet auf-poste-client) + +Upstream Author: + + Progfou + +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 and +is licensed under the GPL, see above. + diff --git a/debian/cron.d b/debian/cron.d new file mode 100644 index 0000000..783c3a7 --- /dev/null +++ b/debian/cron.d @@ -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 index 0000000..b34c28e --- /dev/null +++ b/debian/dirs @@ -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 index 0000000..1912100 --- /dev/null +++ b/debian/lintian-overrides @@ -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 index 0000000..5a64f3f --- /dev/null +++ b/debian/manpages @@ -0,0 +1 @@ +debian/auf-refer.8 diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 0000000..a1dfe59 --- /dev/null +++ b/debian/postinst @@ -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 index 0000000..e8009c0 --- /dev/null +++ b/debian/postrm @@ -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 index 0000000..b2e6ff1 --- /dev/null +++ b/debian/rules @@ -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 -- 1.7.10.4