Intégration de la branche release-6.3.0

This commit is contained in:
Jephté Clain 2017-04-04 04:05:36 +04:00
commit 8de590fb65
13 changed files with 385 additions and 46 deletions

View File

@ -1,3 +1,17 @@
## Version 6.3.0 du 04/04/2017-04:04
* `2fb17f7` implémenter dumpcsv --awk-map
* `42c6fa6` ne pas activer git-ssh.userconf par défaut
* `5061d4b` bug dans les règles par défaut de mssh
* `14c5667` mssh: portage générique de mfssh pour choisir l'exécutable ssh en fonction du réseau source et destination
* `a2480ec` apacheconfig: *.conf matche aussi *.ssl.conf et *-certs.conf
* `95aa12f` Intégration de la branche update-apacheconfig
* `f233ae1` support de l'option -p pour traiter les ligne de la forme <VirtualBox *:PORT>#*ip:IP
* `f908e1c` support de SITE_IP
* `999fb7f` bug
* `37a2dce` apacheconfig -K: support de plus de patterns pour le fichier modèle
* `ab4148c` cgilsxml.py: nouvelles options --first-spec et all-specs
## Version 6.2.0 du 13/03/2017-11:27 ## Version 6.2.0 du 13/03/2017-11:27
* `4a7b14b` ajouter un argument force à testupdated et testnewer * `4a7b14b` ajouter un argument force à testupdated et testnewer

View File

@ -1 +1 @@
6.2.0 6.3.0

View File

@ -59,6 +59,11 @@ OPTIONS
Lors du déploiement de la configuration, les valeurs des variables Lors du déploiement de la configuration, les valeurs des variables
dynamiques sont remplacées dans les fichiers destination. dynamiques sont remplacées dans les fichiers destination.
Les arguments qui restent sont passés tels quels à apache_autoconf Les arguments qui restent sont passés tels quels à apache_autoconf
-p, --fix-ip
Corriger les lignes de la forme '<VirtualHost *:PORT>#*ip:IP' et les
remplacer par '<VirtualHost IP:PORT>'
Cela permet de déployer une version de production des fichiers de
configuration.
-N, --network-config -N, --network-config
Mettre aussi à jour la configuration réseau. Mettre aussi à jour la configuration réseau.
-r, --certsdir CERTSDIR -r, --certsdir CERTSDIR
@ -101,6 +106,7 @@ destdir=
nohideconfig=auto nohideconfig=auto
templateopt= templateopt=
FULLCONF= FULLCONF=
fixip=
netconf= netconf=
aac_certsdir= aac_certsdir=
bits= bits=
@ -133,6 +139,7 @@ args=(
-8,--jessie '$array_add TEMPLATECTL_VARS sysver=jessie' -8,--jessie '$array_add TEMPLATECTL_VARS sysver=jessie'
--bits: bits= --bits: bits=
-u,--update,--deploy action=deploy -u,--update,--deploy action=deploy
-p,--fix-ip fixip=1
-N,--network-config netconf=1 -N,--network-config netconf=1
-r:,--certsdir: aac_certsdir= -r:,--certsdir: aac_certsdir=
--localhosts action=localhosts --localhosts action=localhosts
@ -188,6 +195,7 @@ elif [ "$action" == deploy -o "$action" == localhosts ]; then
args=( args=(
-d "$destdir" --$action -d "$destdir" --$action
${fixip:+--fix-ip}
${netconf:+--network-config} ${netconf:+--network-config}
${aac_certsdir:+-r "$aac_certsdir"} ${aac_certsdir:+-r "$aac_certsdir"}
${oneconf:+--one-conf "$oneconf"} ${oneconf:+--one-conf "$oneconf"}
@ -208,11 +216,11 @@ elif [ "$action" == deploy -o "$action" == localhosts ]; then
"$destdir" "$aac_certsdir" \ "$destdir" "$aac_certsdir" \
"$config" "$oneconf" "$onemodule" "$onesite" \ "$config" "$oneconf" "$onemodule" "$onesite" \
"$custom_sysinfos" "$sysname" "$sysdist" "$sysver" "$bits" \ "$custom_sysinfos" "$sysname" "$sysdist" "$sysver" "$bits" \
"$netconf" || die "$netconf" "$fixip" || die
eend eend
elif [ "$action" == localhosts ]; then elif [ "$action" == localhosts ]; then
etitle "Mise à jour de /etc/hosts" etitle "Mise à jour de /etc/hosts"
apacheconfig_deploy_localhosts "$destdir" "$aac_certsdir" "$onesite" || die apacheconfig_localhosts "$destdir" "$aac_certsdir" "$onesite" || die
eend eend
fi fi
@ -254,14 +262,17 @@ elif [ "$action" == new-site ]; then
ssltempl= ssltempl=
certstempl= certstempl=
wwwtempl= wwwtempl=
array_from_lines templs "$(list_files "$templdir" "*SITE.conf")" array_from_lines clrtempls "$(list_files "$templdir" "*SITE*.conf")"
[ ${#templs[*]} -gt 0 ] && clrtempl="${templs[0]}" array_from_lines ssltempls "$(list_files "$templdir" "*SITE*.ssl.conf")"
array_from_lines templs "$(list_files "$templdir" "*SITE.ssl.conf")" array_from_lines certstempls "$(list_files "$templdir" "*SITE*-certs.conf")"
[ ${#templs[*]} -gt 0 ] && ssltempl="${templs[0]}" for xtempl in "${ssltempls[@]}" "${certstempls[@]}"; do
array_from_lines templs "$(list_files "$templdir" "*SITE-certs.conf")" array_del clrtempls "$xtempl"
[ ${#templs[*]} -gt 0 ] && certstempl="${templs[0]}" done
array_from_lines templs "$(list_dirs "$templdir" "*SITE")" [ ${#clrtempls[*]} -gt 0 ] && clrtempl="${clrtempls[0]}"
[ ${#templs[*]} -gt 0 ] && wwwtempl="${templs[0]}" [ ${#ssltempls[*]} -gt 0 ] && ssltempl="${ssltempls[0]}"
[ ${#certstempls[*]} -gt 0 ] && certstempl="${certstempls[0]}"
array_from_lines wwwtempls "$(list_dirs "$templdir" "*SITE*")"
[ ${#wwwtempls[*]} -gt 0 ] && wwwtempl="${wwwtempls[0]}"
found= found=
for i in "$clrtempl" "$ssltempl" "$certstempl" "$wwwtempl"; do for i in "$clrtempl" "$ssltempl" "$certstempl" "$wwwtempl"; do
@ -273,6 +284,44 @@ elif [ "$action" == new-site ]; then
die "$host n'est pas un nom d'hôte pleinement qualifié" die "$host n'est pas un nom d'hôte pleinement qualifié"
fi fi
hostip=
for i in "$clrtempl" "$ssltempl"; do
[ -n "$i" -a -f "$templdir/$i" ] || continue
quietgrep SITE_IP "$templdir/$i" && { hostip=1; break; }
done
if [ -n "$hostip" ]; then
# Il y a un champ SITE_IP, il faut demander à l'utilisateur l'adresse ip
# correspondante
[[ "$host" == *.* ]] && hostdomain="${host#*.}" || hostdomain=
pri=
hostip=
i=0
while [ $i -lt ${#PUBDOMAINS[*]} ]; do
if [ "${PUBDOMAINS[$i]}" == "$hostdomain" ]; then
pri="$VSPREFIX${host%$hostdomain}${PRIDOMAINS[$i]}"
resolv_ips ips "$pri"
if [ -n "$ips" ]; then
hostip="${ips[0]}"
break
fi
fi
i=$(($i + 1))
done
if [ -z "$hostip" ]; then
pri="$VSPREFIX$host"
resolv_ips ips "$pri"
[ -n "$ips" ] && hostip="${ips[0]}"
fi
if [ -n "$pri" -a -n "$hostip" ]; then
enote "Correspondance automatique $host --> $pri"
read_value "Veuillez confirmer l'adresse IP d'écoute" hostip "$hostip" N
else
enote "Vous devez saisir l'adresse IP privée correspondant à $host"
read_value "Veuillez entrer l'adresse IP *privée* d'écoute" hostip "" N
fi
[ -n "$hostip" ] || ewarn "Vous avez choisi de ne pas spécifier d'adresse IP d'écoute. Il faudra corriger manuellement les fichiers générés"
fi
etitle "$host" etitle "$host"
hostname="${host%%.*}" hostname="${host%%.*}"
clrconf="${clrtempl/SITE/$hostname}" clrconf="${clrtempl/SITE/$hostname}"
@ -283,7 +332,10 @@ elif [ "$action" == new-site ]; then
mkdir -p "$destdir/certsconf" mkdir -p "$destdir/certsconf"
mkdir -p "$destdir/sites" mkdir -p "$destdir/sites"
sedscript="\ sedscript=
[ -n "$hostip" ] && sedscript="$sedscript
s/SITE_IP/$hostip/g"
sedscript="$sedscript
s/SITE.TLD/$host/g s/SITE.TLD/$host/g
s/SITE/$hostname/g" s/SITE/$hostname/g"

View File

@ -11,7 +11,7 @@ complete -F __nutools_host_completion -o default uinst ruinst runs rruns
if __bash_completion_module_enabled ssh; then if __bash_completion_module_enabled ssh; then
shopt -u hostcomplete shopt -u hostcomplete
complete -F _ssh ussh cssh complete -F _ssh ussh cssh mssh
fi fi
if __bash_completion_module_enabled umount; then if __bash_completion_module_enabled umount; then

View File

@ -4,3 +4,12 @@
#DEFAULT_ADMIN=supervision-gdrsi@listes.univ-reunion.fr #DEFAULT_ADMIN=supervision-gdrsi@listes.univ-reunion.fr
#DEFAULT_CERTSDIR=1507-renater #DEFAULT_CERTSDIR=1507-renater
#DEFAULT_CANAME=1507-DigiCertCA.crt #DEFAULT_CANAME=1507-DigiCertCA.crt
# Valeurs des domaines publics et privés ainsi que préfixe pour les adresses de
# service. Chaque élément du tableau PUBDOMAINS doit avoir un correspondant dans
# le tableau PRIDOMAINS.
# Avec la configuration par défaut suivante, on considère que l'adresse
# privée correspondant à HOST.univ-reunion.fr est vs-HOST.univ.run
#PUBDOMAINS=(univ-reunion.fr)
#PRIDOMAINS=(univ.run)
#VSPREFIX=vs-

23
lib/default/mssh Normal file
View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# Réseaux
NETWORKS=(
ur # université de la réunion
ksct # ks.jclain.fr
)
ur_INCLUDES=(10/8)
ur_EXCLUDES=(10.42/16)
ur_DOMAINS=(univ.run univ-reunion.fr)
ksct_INCLUDES=(192.168.97/24)
ksct_EXCLUDES=()
ksct_DOMAINS=(ct)
# Règles de la forme FROM:TO:SSH
RULES=(
ksct:ksct:ssh
:ksct:kssh
ur::ssh
:ur:fssh
)

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# Spécifier le client SSH à utiliser pour git
#export GIT_SSH=mssh

View File

@ -1 +1 @@
014002000 014003000

View File

@ -325,6 +325,7 @@ function apache_autoconf() {
local sitesdir onesite cgibindir wwwdir certsconfdir rrdir onecms local sitesdir onesite cgibindir wwwdir certsconfdir rrdir onecms
local sysname sysdist sysver bits local sysname sysdist sysver bits
local netconf destconfsdir a2xconf local netconf destconfsdir a2xconf
local fixip
local restart=1 local restart=1
parse_opts "${PRETTYOPTS[@]}" \ parse_opts "${PRETTYOPTS[@]}" \
--help '$exit_with __display_apache_autoconf_help' \ --help '$exit_with __display_apache_autoconf_help' \
@ -349,6 +350,7 @@ function apache_autoconf() {
-8,--jessie sysver=jessie \ -8,--jessie sysver=jessie \
--bits: bits= \ --bits: bits= \
--network-config netconf=1 \ --network-config netconf=1 \
--fix-ip fixip=1 \
@ args -- "$@" && set -- "${args[@]}" || die "$args" @ args -- "$@" && set -- "${args[@]}" || die "$args"
if [ -n "$sysname" -o -n "$sysdist" -o -n "$sysver" ]; then if [ -n "$sysname" -o -n "$sysdist" -o -n "$sysver" ]; then
@ -400,6 +402,10 @@ function apache_autoconf() {
# valeur dans les fichiers # valeur dans les fichiers
local -a FILLVARS; local FILLSCRIPT FILLTEMP local -a FILLVARS; local FILLSCRIPT FILLTEMP
__apache_autoconf_fillxxx "$@" __apache_autoconf_fillxxx "$@"
if [ -n "$fixip" ]; then
FILLSCRIPT="$FILLSCRIPT
"'s/<VirtualHost \*:\([0-9][0-9]*\)>#\*ip:\(.*\)$/<VirtualHost \2:\1>/'
fi
# Installation des packages système # Installation des packages système
if [ -f "$confdir/syspkgs.conf" ]; then if [ -f "$confdir/syspkgs.conf" ]; then
@ -884,6 +890,9 @@ function apacheconfig_initvars() {
DEFAULT_ADMIN=supervision-gdrsi@listes.univ-reunion.fr DEFAULT_ADMIN=supervision-gdrsi@listes.univ-reunion.fr
DEFAULT_CERTSDIR=1507-renater DEFAULT_CERTSDIR=1507-renater
DEFAULT_CANAME=1507-DigiCertCA.crt DEFAULT_CANAME=1507-DigiCertCA.crt
PUBDOMAINS=(univ-reunion.fr)
PRIDOMAINS=(univ.run)
VSPREFIX=vs-
set_defaults apacheconfig set_defaults apacheconfig
TEMPLATE_NOWRITE_VARS=("${APACHECONFIG_TEMPLATE_NOWRITE_VARS[@]}") TEMPLATE_NOWRITE_VARS=("${APACHECONFIG_TEMPLATE_NOWRITE_VARS[@]}")
@ -951,7 +960,7 @@ function apacheconfig_deploy() {
local destdir="$1" certsdir="$2"; shift; shift local destdir="$1" certsdir="$2"; shift; shift
local config="$1" oneconf="$2" onemodule="$3"; onesite="$4"; shift; shift; shift; shift local config="$1" oneconf="$2" onemodule="$3"; onesite="$4"; shift; shift; shift; shift
local custom_sysinfos="$1" sysname="$2" sysdist="$3" sysver="$4" bits="$5"; shift; shift; shift; shift; shift local custom_sysinfos="$1" sysname="$2" sysdist="$3" sysver="$4" bits="$5"; shift; shift; shift; shift; shift
local netconf="$1"; shift local netconf="$1" fixip="$2"; shift; shift
local -a args local -a args
args=(--ignore "$(basename -- "$config")") args=(--ignore "$(basename -- "$config")")
@ -960,6 +969,7 @@ function apacheconfig_deploy() {
[ -n "$onesite" ] && array_add args --one-site "$(basename -- "$onesite")" [ -n "$onesite" ] && array_add args --one-site "$(basename -- "$onesite")"
[ -n "$custom_sysinfos" ] && array_add args --sysname "$sysname" --sysdist "$sysdist" --sysver "$sysver" --bits "$bits" [ -n "$custom_sysinfos" ] && array_add args --sysname "$sysname" --sysdist "$sysdist" --sysver "$sysver" --bits "$bits"
[ -n "$netconf" ] && array_add args --network-config [ -n "$netconf" ] && array_add args --network-config
[ -n "$fixip" ] && array_add args --fix-ip
array_add args "$destdir" "$certsdir" array_add args "$destdir" "$certsdir"
for __name in "${TEMPLATE_DYNAMIC_VARS[@]}"; do for __name in "${TEMPLATE_DYNAMIC_VARS[@]}"; do
array_add args "$__name=${!__name}" array_add args "$__name=${!__name}"
@ -970,8 +980,7 @@ function apacheconfig_deploy() {
function apacheconfig_qs() { function apacheconfig_qs() {
# fonction pour simplifier l'utilisation de apacheconfig_deploy pour un # fonction pour simplifier l'utilisation de apacheconfig_deploy pour un
# répertoire spécifique # répertoire spécifique
# $1=destdir $2=certsdir $3=netconf # $1=destdir $2=certsdir $3=netconf $4=fixip
local destdir="$1" certsdir="$2" netconf="$3"
local config modified destdir autocreate local config modified destdir autocreate
apacheconfig_initvars apacheconfig_initvars
apacheconfig_loadconf "$1" apacheconfig_loadconf "$1"
@ -979,7 +988,7 @@ function apacheconfig_qs() {
"$destdir" "$2" \ "$destdir" "$2" \
"$config" "" "" "" \ "$config" "" "" "" \
"" "" "" "" "" \ "" "" "" "" "" \
"$3" "$3" "$4"
} }
function apacheconfig_localhosts() { function apacheconfig_localhosts() {

View File

@ -1758,7 +1758,7 @@ function sortcsv() { LANG=C lsortcsv "$@"; }
################################################################################ ################################################################################
__DUMPCSV_HELP="\ __DUMPCSV_HELP="\
Afficher les champs spécifiés pour traitement par le shell Afficher les champs spécifiés pour traitement par le shell ou par awk
-S, --skip-lines nblines -S, --skip-lines nblines
Sauter nblines au début du flux Sauter nblines au début du flux
@ -1785,7 +1785,7 @@ Afficher les champs spécifiés pour traitement par le shell
Spécifier le nom à utiliser pour afficher les en-têtes avec l'option -h Spécifier le nom à utiliser pour afficher les en-têtes avec l'option -h
-n, --name NAME -n, --name NAME
Spécifier le nom à utiliser pour les options -f, -a, -b Spécifier le nom à utiliser pour les options -f, -a, -b, -w
-f, --function -f, --function
Afficher les champs comme l'appel d'une fonction, e.g: Afficher les champs comme l'appel d'une fonction, e.g:
dump value00 value01... dump value00 value01...
@ -1815,6 +1815,28 @@ Afficher les champs spécifiés pour traitement par le shell
Le nom du tableau est fixé à 'values'. L'option -n permet de spécifier le Le nom du tableau est fixé à 'values'. L'option -n permet de spécifier le
nom de la fonction, qui vaut 'dump' par défaut. Avec -h le nom par défaut nom de la fonction, qui vaut 'dump' par défaut. Avec -h le nom par défaut
est 'dumph' est 'dumph'
-w, --awk-map
Afficher les champs comme une fonction awk qui permet de rechercher une
valeur et d'afficher la valeur correspondante. L'option -n permet de
spécifier le nom de la fonction, qui vaut 'mapval' par défaut.
--wtype TYPE
Spécifier le type de fonction à générer avec l'option --awk-map. Le type par
défaut est 'value'
Avec le type 'value', la fonction générée est de la forme dump(inval). Cette
fonction prend en argument la valeur de la colonne spécifiée avec --wscol,
et si cette valeur est trouvée dans les données, retourner la valeur de la
colonne spécifiée avec --wrcol
Avec le type 'array', la fonction générée est de la forme dump(inval, outvs)
Cette fonction prend en argument la valeur de la colonne spécifiée avec
--wscol, et si cette valeur est trouvée dans les données, le tableau outvs
est rempli avec les donnée de la ligne correspondante.
--wscol SFIELD
Nom du champ qui est cherché par la fonction générée avec l'option --awk-map
La valeur par défaut est '1', c'est à dire le premier champ.
--wrcol RFIELD
Nom du champ dont la valeur est retournée par la fonction générée avec
l'option '--awk-map --wtype value' en cas de correspondance.
La valeur par défaut est '2', c'est à dire le deuxième champ.
-v, --var -v, --var
Affiche les champ en initialisant des variables, e.g: Affiche les champ en initialisant des variables, e.g:
names=(header0 header1) names=(header0 header1)
@ -1838,6 +1860,7 @@ function ldumpcsv() {
eval "$(utools_local)" eval "$(utools_local)"
local skip= parse_headers=1 keepf skipf show_headers local skip= parse_headers=1 keepf skipf show_headers
local dump=function reset=1 name hname local dump=function reset=1 name hname
local wtype wscol wrcol
parse_opts "${PRETTYOPTS[@]}" \ parse_opts "${PRETTYOPTS[@]}" \
-S:,--skip:,--skip-lines:,--skiplines: skip= \ -S:,--skip:,--skip-lines:,--skiplines: skip= \
-H,--parse-headers parse_headers=1 \ -H,--parse-headers parse_headers=1 \
@ -1852,6 +1875,10 @@ function ldumpcsv() {
--reset reset=1 \ --reset reset=1 \
--no-reset reset= \ --no-reset reset= \
-b,--array-function dump=array-function \ -b,--array-function dump=array-function \
-w,--awk-map dump=awk-map \
--wtype: wtype= \
--wscol: wscol= \
--wrcol: wrcol= \
-v,--var dump=var \ -v,--var dump=var \
@ args -- "$@" && set -- "${args[@]}" || die "$args" @ args -- "$@" && set -- "${args[@]}" || die "$args"
@ -1876,13 +1903,64 @@ function ldumpcsv() {
case "$dump" in case "$dump" in
function|array-function) name=dump;; function|array-function) name=dump;;
array) name=values;; array) name=values;;
awk-map) name=mapval;;
esac esac
fi fi
case "${wtype:-value}" in
array|a) wtype=array;;
value|v) wtype=value;;
esac
[ -n "$wscol" ] || wscol=1
[ -n "$wrcol" ] || wrcol=2
local -a fields local -a fields
fields=("$@") fields=("$@")
awkcsv "${args[@]}" -v show_headers:int="$show_headers" -v hname="$hname" -v name="$name" -v dump="$dump" -v reset_values:int="$reset" -v fields[@] -e ' awkcsv "${args[@]}" -v show_headers:int="$show_headers" \
-v hname="$hname" -v name="$name" -v dump="$dump" \
-v reset_values:int="$reset" -v fields[@] \
-v wtype="$wtype" -v wscol="$wscol" -v wrcol="$wrcol" \
-e '
function init_fields() {
if (do_once("init_fields")) {
if (fields_count == 0) {
array_copy(fields, HEADERS)
fields_count = array_len(fields)
}
}
}
function before_awkmap(name, wtype) {
if (do_once("before_awkmap")) {
if (wtype == "value") {
print "function " name "(inval) {"
} else if (wtype == "array") {
print "function " name "(inval, outvs) {"
}
}
}
function awkmap(inval, outval, values, count, wtype, i) {
if (wtype == "value") {
print "if (inval == " qawk(inval) ") return " qawk(outval)
} else if (wtype == "array") {
print "if (inval == " qawk(inval) ") {"
print "delete outvs"
for (i = 1; i <= count; i++) {
print "outvs[" i "] = " qawk(values[i])
}
print "return 1"
print "}"
}
}
function after_awkmap() {
if (do_once("after_awkmap")) {
if (wtype == "value") {
print "return \"\""
} else if (wtype == "array") {
print "return 0"
}
print "}"
}
}
function dump_values(name, values, dump) { function dump_values(name, values, dump) {
if (dump == "function") { if (dump == "function") {
print qarr(values, name) print qarr(values, name)
@ -1899,12 +1977,8 @@ function dump_values(name, values, dump) {
} }
} }
} }
function init_fields() { function before_dump() {
if (do_once("init_fields")) { if (do_once("before_dump")) {
if (fields_count == 0) {
array_copy(fields, HEADERS)
fields_count = array_len(fields)
}
if (show_headers) { if (show_headers) {
dump_values(hname, fields, dump == "var"? "array": dump) dump_values(hname, fields, dump == "var"? "array": dump)
} }
@ -1922,10 +1996,26 @@ function init_fields() {
values[i] = get(fields[i]) values[i] = get(fields[i])
i++ i++
} }
if (dump == "awk-map") {
before_awkmap(name, wtype)
if (wscol ~ /^[0-9]+$/) inval = geti(wscol)
else inval = get(wscol)
if (wrcol ~ /^[0-9]+$/) outval = geti(wrcol)
else outval = get(wrcol)
awkmap(inval, outval, values, fields_count, wtype)
} else {
before_dump()
dump_values(name, values, dump) dump_values(name, values, dump)
} }
}
END { END {
init_fields() if (dump == "awk-map") {
before_awkmap(name, wtype)
after_awkmap()
} else {
before_dump()
}
}' -a '' }' -a ''
} }

View File

@ -1780,6 +1780,12 @@ function unquote_html(s) {
gsub(/&amp;/, "\\&", s) gsub(/&amp;/, "\\&", s)
return s return s
} }
function qawk(s) {
gsub(/\\/, "\\\\", s)
gsub(/"/, "\\\"", s)
gsub(/\n/, "\\n", s)
return "\"" s "\""
}
function qval(s) {'" function qval(s) {'"
gsub(/'/, \"'\\\\''\", s) gsub(/'/, \"'\\\\''\", s)
return \"'\" s \"'\" return \"'\" s \"'\"

View File

@ -179,7 +179,7 @@ class File:
else: self.vars[name] = value else: self.vars[name] = value
def __repr__(self): return 'File<%s>' % (self.pf) def __repr__(self): return 'File<%s>' % (self.pf)
def find_files(basedir, filters): def find_files(basedir, filters, spec_method='all'):
basedir = path.abspath(basedir) basedir = path.abspath(basedir)
files = [] files = []
deep_filters = [filter for filter in filters if filter.re_spec is not None and filter.deep_scan] deep_filters = [filter for filter in filters if filter.re_spec is not None and filter.deep_scan]
@ -190,11 +190,21 @@ def find_files(basedir, filters):
# exception se produit # exception se produit
try: file = File(dirpath, filename) try: file = File(dirpath, filename)
except: continue except: continue
matched = False matched1 = matched = False
allowed = False allowed1 = allowed = False
for filter in deep_filters: for filter in deep_filters:
matched = filter.match_fill(file, basedir) or matched if spec_method == 'all' or \
allowed = filter.match_allow(file) or allowed (spec_method == 'first' and not matched):
matched1 = filter.match_fill(file, basedir)
else:
matched1 = False
matched = matched1 or matched
if spec_method == 'all' or \
(spec_method == 'first' and matched and not allowed):
allowed1 = filter.match_allow(file)
else:
allowed1 = False
allowed = allowed1 or allowed
if matched: pass if matched: pass
elif allowed: file.dontlist = True elif allowed: file.dontlist = True
else: continue else: continue
@ -207,11 +217,21 @@ def find_files(basedir, filters):
try: file = File(basedir, name) try: file = File(basedir, name)
except: continue except: continue
if not file.isfile(): continue if not file.isfile(): continue
matched = False matched1 = matched = False
allowed = False allowed1 = allowed = False
for filter in simple_filters: for filter in simple_filters:
matched = filter.match_fill(file) or matched if spec_method == 'all' or \
allowed = filter.match_allow(file) or allowed (spec_method == 'first' and not matched):
matched1 = filter.match_fill(file, basedir)
else:
matched1 = False
matched = matched1 or matched
if spec_method == 'all' or \
(spec_method == 'first' and matched and not allowed):
allowed1 = filter.match_allow(file)
else:
allowed1 = False
allowed = allowed1 or allowed
if matched: pass if matched: pass
elif allowed: file.dontlist = True elif allowed: file.dontlist = True
else: continue else: continue
@ -411,6 +431,7 @@ def run_cgilsxml():
charset = 'utf-8' charset = 'utf-8'
default_content = ContentInfos() default_content = ContentInfos()
default_filter = Filter(r'(.*)') default_filter = Filter(r'(.*)')
env = dict(filters=[], filter=None)
def add_spec(option, opt, value, parser, *args, **kw): def add_spec(option, opt, value, parser, *args, **kw):
if env['filter'] is not None: env['filters'].append(env['filter']) if env['filter'] is not None: env['filters'].append(env['filter'])
env['filter'] = Filter(spec=value) env['filter'] = Filter(spec=value)
@ -420,16 +441,16 @@ def run_cgilsxml():
def allow_spec(option, opt, value, parser, *args, **kw): def allow_spec(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter if env['filter'] is None: env['filter'] = default_filter
env['filter'].allow_spec(value) env['filter'].allow_spec(value)
def add_var(option, opt_str, value, parser, *args, **kw): def add_var(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter if env['filter'] is None: env['filter'] = default_filter
env['filter'].add_var(value) env['filter'].add_var(value)
def set_group(option, opt_str, value, parser, *args, **kw): def set_group(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter if env['filter'] is None: env['filter'] = default_filter
env['filter'].set_group(value) env['filter'].set_group(value)
def set_break_on(option, opt_str, value, parser, *args, **kw): def set_break_on(option, opt, value, parser, *args, **kw):
if env['filter'] is None: env['filter'] = default_filter if env['filter'] is None: env['filter'] = default_filter
env['filter'].set_break_on(value) env['filter'].set_break_on(value)
def set_content_disposition(option, opt_str, value, parser, *args, **kw): def set_content_disposition(option, opt, value, parser, *args, **kw):
if value in ('attachment', 'inline'): pass if value in ('attachment', 'inline'): pass
elif value == 'none': value = None elif value == 'none': value = None
else: else:
@ -441,15 +462,16 @@ def run_cgilsxml():
sys.exit(1) sys.exit(1)
if env['filter'] is None: default_content.disposition = value if env['filter'] is None: default_content.disposition = value
else: env['filter'].force_disposition = value else: env['filter'].force_disposition = value
def set_content_type(option, opt_str, value, parser, *args, **kw): def set_content_type(option, opt, value, parser, *args, **kw):
if env['filter'] is None: default_content.type = value if env['filter'] is None: default_content.type = value
else: env['filter'].force_type = value else: env['filter'].force_type = value
def set_content_charset(option, opt_str, value, parser, *args, **kw): def set_content_charset(option, opt, value, parser, *args, **kw):
if env['filter'] is None: default_content.charset = value if env['filter'] is None: default_content.charset = value
else: env['filter'].force_charset = value else: env['filter'].force_charset = value
from optparse import OptionParser from optparse import OptionParser
OP = OptionParser(usage=u"\n\t%prog [options] /path/to/dir", description=__doc__) OP = OptionParser(usage=u"\n\t%prog [options] /path/to/dir", description=__doc__)
OP.set_defaults(spec_method='all')
OP.add_option('-e', '--spec', dest='spec', action='callback', callback=add_spec, type='string', OP.add_option('-e', '--spec', dest='spec', action='callback', callback=add_spec, type='string',
help=u"Spécifier l'expression régulière permettant de sélectionner les fichiers à lister. " help=u"Spécifier l'expression régulière permettant de sélectionner les fichiers à lister. "
+ u"La correspondance est tentée sur le nom du fichier avec la fonction match(). " + u"La correspondance est tentée sur le nom du fichier avec la fonction match(). "
@ -460,6 +482,10 @@ def run_cgilsxml():
+ u"\n Il est possible de spécifier cette option plusieurs fois." + u"\n Il est possible de spécifier cette option plusieurs fois."
+ u"\n Note: TOUTES les expressions régulières sont testées par rapport au nom du fichier, et pour celles qui correspondent, les variables correspondantes sont définies. " + u"\n Note: TOUTES les expressions régulières sont testées par rapport au nom du fichier, et pour celles qui correspondent, les variables correspondantes sont définies. "
+ u"Il faut donc ordonner les expressions régulières de la plus générale à la plus spécifique, contrairement à ce qui se fait d'habitude.") + u"Il faut donc ordonner les expressions régulières de la plus générale à la plus spécifique, contrairement à ce qui se fait d'habitude.")
OP.add_option('--all-specs', dest='spec_method', action='store_const', const='all',
help=u"Avec l'option -e, tester toutes les expressions régulières dans l'ordre de définition. C'est le comportement par défaut.")
OP.add_option('--first-spec', dest='spec_method', action='store_const', const='first',
help=u"Avec l'option -e, arrêter à la première expression régulière qui correspond")
OP.add_option('--glob', dest='pattern', action='callback', callback=add_glob, type='string', OP.add_option('--glob', dest='pattern', action='callback', callback=add_glob, type='string',
help=u"Comme --spec, mais en utilisant les patterns du shell *, ?, [seq], [!seq]. " help=u"Comme --spec, mais en utilisant les patterns du shell *, ?, [seq], [!seq]. "
+ u"Si l'expression contient un caractère '/', la correspondance se fait sur le chemin complet du fichier avec le module glob. " + u"Si l'expression contient un caractère '/', la correspondance se fait sur le chemin complet du fichier avec le module glob. "
@ -533,7 +559,6 @@ def run_cgilsxml():
+ u"Il est possible de spécifier plusieurs paramètres en les séparant par des virgules.") + u"Il est possible de spécifier plusieurs paramètres en les séparant par des virgules.")
OP.add_option('-p', '--prefix', dest="prefix", OP.add_option('-p', '--prefix', dest="prefix",
help=u"Ajouter les paramètres supplémentaires spécifiés à /result/env/query_string.") help=u"Ajouter les paramètres supplémentaires spécifiés à /result/env/query_string.")
env = dict(filters=[], filter=None)
o, args = OP.parse_args() o, args = OP.parse_args()
filters = env['filters'] filters = env['filters']
filter = env['filter'] filter = env['filter']
@ -577,7 +602,7 @@ def run_cgilsxml():
files = [] files = []
for basedir in args: for basedir in args:
files.extend(find_files(basedir, filters)) files.extend(find_files(basedir, filters, o.spec_method))
sortfunc = build_sortfunc(sortby) sortfunc = build_sortfunc(sortby)
files = sort_files(files, sortfunc) files = sort_files(files, sortfunc)
fgroups = build_fgroups(files) fgroups = build_fgroups(files)

107
mssh Executable file
View File

@ -0,0 +1,107 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib"
urequire DEFAULTS ipcalc
if [ $# -eq 1 -a "$1" == "--help" ]; then
exit_with uecho "$scriptname: Faire une connexion ssh en utilisant l'exécutable approprié au réseau source et destination
USAGE
$scriptname [user@]host"
fi
# fonctions de support
function match_network() {
local ip="$1" network="$2"
local -a includes excludes domains
local spec
array_copy includes "${network}_INCLUDES"
array_copy excludes "${network}_EXCLUDES"
array_copy domains "${network}_DOMAINS"
if ipcalc_checkip "$ip" >/dev/null; then
for spec in "${excludes[@]}"; do
if ipcalc_match "$ip" "$spec"; then
return 1
fi
done
for spec in "${includes[@]}"; do
if ipcalc_match "$ip" "$spec"; then
return 0
fi
done
else
for spec in "${domains[@]}"; do
[[ "$ip" == *."$spec" ]] && return 0
done
fi
return 1
}
# paramètres de l'environnement
DO=
if [ "$1" == --debug ]; then
# Activer le mode DEBUG
shift
set_verbosity -D
elif [ "$1" == --trace ]; then
# Activer le mode DEBUG
shift
set_verbosity -D
TRACE=1
DO=qvals
fi
NETWORKS=()
RULES=()
set_defaults mssh
# déterminer d'où l'on vient
from=
array_from_lines myips "$(ip addr | awk '$1 == "inet" { gsub(/\/.*/, "", $2); print $2 }')"
for network in "${NETWORKS[@]}"; do
for myip in "${myips[@]}"; do
if match_network "$myip" "$network"; then
from="$network"
break
fi
done
[ -n "$from" ] && break
done
edebug "FROM: ${from:-ANY} (${myips[*]})"
# analyser la ligne de commande
vars="$("$scriptdir/ussh" --parse "$@")" || exit 1
[ -n "$TRACE" ] && echo "$vars"
eval "$vars"
for userhost in "${hosts[@]}"; do
# déterminer où l'on veut aller
splituserhost "$userhost" user host
to=
for network in "${NETWORKS[@]}"; do
if match_network "$host" "$network"; then
to="$network"
break
fi
done
edebug "TO: ${to:-ANY} ($host)"
# Sélectionner la commande ssh à utiliser
found=
for rule in "${RULES[@]}"; do
splitfsep "$rule" : rfrom rule2
splitfsep "$rule2" : rto rssh
if [ \( -z "$rfrom" -o "$from" == "$rfrom" \) -a \
\( -z "$rto" -o "$to" == "$rto" \) ]; then
found=1
$DO ${exec:+exec} "$rssh" "${options[@]}" "$userhost" "${args[@]}"
break
fi
done
if [ -z "$found" ]; then
$DO ${exec:+exec} "$ssh" "${options[@]}" "$userhost" "${args[@]}"
fi
done