Intégration de la branche release-9.4.1

This commit is contained in:
Jephté Clain 2020-01-20 14:46:16 +04:00
commit 1210ca7382
24 changed files with 2306 additions and 222 deletions

View File

@ -1,3 +1,67 @@
## Version 9.4.1 du 20/01/2020-14:46
* `6f01bac` dk: si la commande est inconnue, la transmettre à docker
* `175f6ed` cssh: traiter le cas où screen n'est pas disponible
* `73db728` umail: possibilité de spécifier le type de body
* `5fc55cc` dk: support des fonctions de nettoyage par profil
* `21274af` dk: APPS peut avoir une valeur dépendante du profil
* `f7f8889` support des filtres avec wildcards
* `747c563` repoctl: divers bugs
* `4fdd23c` dk: support limité de podman
* `5457228` dk: support des aliases pour les mappings pff
* `a55f9c4` dk: ajout de get-profile
* `ac7efad` dk: possibilité de forcer la suppression des images
* `5284838` typo
* `d5c5162` dk: dans build.env, une variable peut en mentionner une autre
* `f7d036a` repoctl: cosmetic
* `87b8d5b` Intégration de la branche update-repoctl
* `0866bbd` finaliser edit et implémenter get
* `8daf4ec` début implémentation edit
* `ef1c8f2` utiliser dk composer, et ne pas utiliser de container par défaut
* `269379f` dk: rendre le code overridable
* `aae3703` bug avec traitement des variables de docker-machine -u
* `f875093` dk: par défaut, forcer l'utilisation de la machine locale pour dk composer
* `c202a27` dk: support COMPOSER_SETUP et COMPOSER_CMD
* `921caa1` dk: le shell est lancé en root
* `ce98445` dk: support de composer shell
* `2b5ed18` dk: ajouter un frontend pour composer
* `29c54e7` dmctl: import/export de docker machines
* `de53bae` Intégration de la branche add-repoctl
* `600b824` support limité de pcrone et pclone
* `914f635` implémentation initiale de create, list, delete
* `a774497` squelette
* `5a444a6` dk: support pff
* `425e8a5` dk: maj format ps
* `52c3d7a` dk: ps, ls et rm prennent des filtres. ajout de pull
* `d5f8fa4` cx-updatedev: ajout de l'option -g
* `5fe5137` dk: support de COMPOSER_ACTION et sqlmig NOFIX
* `74cf35b` typo
* `0468623` alias pour docer-machine
* `3dfe542` dk: support de scripts génériques
* `488a257` délai pour éviter les maj intempestives d'eclipse
* `13ce5b8` dk: tagger aussi avec la distribution
* `d03b04f` dk: ajouter automatiquement le suffixe -$DIST à la version
* `6879491` maj doc
* `7fad363` cssh: compat avec les vieilles versionsd de linux
* `f65dda6` bug
* `bc7eebc` ajouter --with-registry-auth à dk update
* `8af50f4` nettoyage de logs webobjects
* `458ccd3` dk: support de certaines options pour dk run
* `c97bc6a` dk: support de la commande run
* `ae70f66` synchro des dépendances uniquement pour le type composer
* `f508dae` support des mises à jour en mode devel
* `60a4c73` cx-conndev: ajouter l'option -d
* `85ac283` cx-conndev: renommer l'option en --mysql-cmd
* `80db462` cx-conndev: ajout de l'option --cmd
* `4400ba7` ajout de ensure-vip
* `ae7ffeb` cx-updatedev: remplacer --ru par -w, --ud, --ur en fonction des besoins
* `9bfd515` dk -c est auto-complete friendly
* `a5a41d9` dk: support de fichiers compose non défaut
* `7e5859e` bug
* `b342960` bug
* `c44d1d3` dk: par défaut, ne pas ajouter le profil au nom de projet
* `aa4eb4a` cx-updatedev: ajout des mises à jour récursives
## Version 9.4.0 du 05/06/2019-10:15 ## Version 9.4.0 du 05/06/2019-10:15
* `fb96852` Intégration de la branche dk-deploy * `fb96852` Intégration de la branche dk-deploy

View File

@ -1 +1 @@
9.4.0 9.4.1

13
cssh
View File

@ -32,9 +32,22 @@ function __ask() {
} }
function __auto_screen() { function __auto_screen() {
# Si screen pas installé, ne rien faire
if [ -z "$(which screen 2>/dev/null)" ]; then
echo "'"$COULEUR_JAUNE"'WARNING'"$COULEUR_NORMALE"' screen introuvable. une session bash classique sera lancée"
exec /bin/bash -l
fi
# Si on est déjà dans screen, ne rien faire # Si on est déjà dans screen, ne rien faire
[ -z "$STY" ] || return [ -z "$STY" ] || return
# corriger TERM pour les vieilles versions de Linux
case "$TERM" in
xterm*) TERM=xterm;;
screen*) TERM=screen;;
esac
export TERM
local msgprefix local msgprefix
local screens count local screens count

View File

@ -8,16 +8,34 @@ function display_help() {
USAGE USAGE
$scriptname [DATABASE] $scriptname [DATABASE]
$scriptname -c|-d [-uUSER [-pPASSWORD]] ...
OPTIONS OPTIONS
-h, -s, --service SERVICE -h, -s, --service SERVICE
Spécifier le nom du service. La valeur par défaut est db" Spécifier le nom du service. La valeur par défaut est db
-c, --mysql-cmd
Lancer 'mysql -hSERVICE_IP' avec les arguments supplémentaires fournis
sur la ligne de commande
-d, --mysqldump-cmd
Lancer 'mysqldump --databases --add-drop-database -hSERVICE_IP' avec
les arguments supplémentaires fournis sur la ligne de commande
-u, --user USER
-p, --password PASSWORD
Paramètres supplémentaires utilisés uniquement avec les options -c et -d"
} }
service=db service=db
mysql_cmd=
mysqldump_cmd=
user=
password=
args=( args=(
--help '$exit_with display_help' --help '$exit_with display_help'
-h:,-s:,--service: service= -h:,-s:,--service: service=
-c,--mysql-cmd mysql_cmd=1
-d,--mysqldump-cmd mysqldump_cmd=1
-u:,--user: user=
-p:,--password: password=
) )
parse_args "$@"; set -- "${args[@]}" parse_args "$@"; set -- "${args[@]}"
@ -44,7 +62,7 @@ fi
### ###
function die_not_found() { die "$service: service introuvable"; } function die_not_found() { die "$service: service introuvable. vérifiez que le projet est actuellement up"; }
setx cid=docker-compose ps -q "$service" 2>/dev/null || die_not_found setx cid=docker-compose ps -q "$service" 2>/dev/null || die_not_found
[ -n "$cid" ] || die_not_found [ -n "$cid" ] || die_not_found
edebug "$service id: $cid" edebug "$service id: $cid"
@ -54,7 +72,15 @@ setx ip=docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{en
[ -n "$ip" ] || die_not_found [ -n "$ip" ] || die_not_found
edebug "$service ip: $ip" edebug "$service ip: $ip"
mysqlcmd="$(php bin/conndev.php "$ip" "$@")" if [ -n "$mysql_cmd" ]; then
edebug "mysqlcmd: $mysqlcmd" mysql -h"$ip" ${user:+-u"$user"} ${password:+-p"$password"} "$@"
eval "$mysqlcmd" elif [ -n "$mysqldump_cmd" ]; then
mysqldump --databases --add-drop-database -h"$ip" ${user:+-u"$user"} ${password:+-p"$password"} "$@"
else
mysql_cmd="$(php bin/conndev.php "$ip" "$@")"
edebug "mysql_cmd: $mysql_cmd"
eval "$mysql_cmd"
fi

View File

@ -17,34 +17,75 @@ OPTIONS
Afficher simplement ce qui serait fait Afficher simplement ce qui serait fait
-q, --quiet -q, --quiet
Ne pas lancer rsync en mode verbose Ne pas lancer rsync en mode verbose
-g, --no-wait
Ne pas attendre avant de faire git commit
--rsync
Mettre à jour les répertoires dans vendor/ qui ne sont pas des liens
symboliques à partir des projets dépendants correspondants. Les liens
symboliques créés avec --link sont ignorés. C'est l'option par défaut.
-l, --link -l, --link
Transformer les clones de dépôts en liens directs vers les projets Transformer les clones de dépôts dans vendor/ en liens symboliques vers
les projets dépendants correpondants.
-k, --copy -k, --copy
Transformer les liens directs vers les projets en copies des projets Transformer les liens symboliques dans vendor/ en copies des projets
dépendants correspondants. Les répertoires qui ne sont pas des liens
symboliques sont ignorés.
Cette option peut être considérée comme le contraire de --link
-i, --install -i, --install
Supprimer les répertoires et les faire recréer par composer i Supprimer les répertoires des projets dépendants dans vendor/, qu'il
s'agisse de liens symboliques ou de répertoires normaux, puis les faire
recréer par 'composer i'
Celà permet de ramener le projet à l'état original.
-j, --reinstall-link -j, --reinstall-link
Supprimer les répertoires et les faire recréer par composer i, Supprimer les répertoires des projets dépendants dans vendor/ s'il
uniquement s'il s'agit de liens s'agit de liens symboliques, puis les faire recréer par 'composer i'
Cette variante est plus rapide que --install puisqu'on ne cherche pas à
tout recréer.
-u, --update -u, --update
Supprimer les répertoires et les faire recréer par composer u" Supprimer les répertoires des projets dépendants dans vendor/, qu'il
s'agisse de liens symboliques ou de répertoires normaux, puis les faire
recréer par 'composer u'
Celà permet de mettre à jour le projet sans les erreurs qui résultent
des modifications faites par les autres actions.
-w, --update-commit
Mettre à jour le projet avec --update puis enregistrer les modifications
éventuelles dans git
--ud, --update-deps
Mettre à jour les projets dépendants avec --update-commit avant de
mettre à jour le projet courant.
--ur, --update-recursive
Mettre à jour de façon récursive tous les projets dépendants.
NB: les modifications dans les projets dépendants seront automatiquement
enregistrées dans git."
} }
fake= fake=
verbose=1 verbose=1
action= nowait=
action=rsync
args=( args=(
--help '$exit_with display_help' --help '$exit_with display_help'
-d:,--project-dir: projdir=
-n,--fake fake=1 -n,--fake fake=1
-q,--quiet verbose= -q,--quiet verbose=
-g,--no-wait nowait=1
-l,--link action=link -l,--link action=link
-k,--copy action=copy -k,--copy action=copy
-i,--install action=install -i,--install action=install
-j,--reinstall-link action=reinstall-link -j,--reinstall-link action=reinstall-link
-u,--update action=update -u,--update action=update
-w,--update-commit action=update-commit
--ud,--update-deps action=update-deps
--ur,--update-recursive action=update-recursive
) )
parse_args "$@"; set -- "${args[@]}" parse_args "$@"; set -- "${args[@]}"
if [ -d "$projdir" ]; then
cd "$projdir"
elif [ -e "$projdir" ]; then
die "$projdir: répertoire introuvable"
fi
found= found=
first=1 first=1
while true; do while true; do
@ -62,11 +103,11 @@ if [ -z "$first" ]; then
enote "Le répertoire du projet est $(ppath . ~)" enote "Le répertoire du projet est $(ppath . ~)"
fi fi
case "$action" in if [ "$action" == update-deps -o "$action" == update-recursive ]; then
install|update) # avec update-deps et update-recursive, tous les modules doivent être
[ -x ./composer.phar ] || die "Impossible de trouver composer.phar" # considérés
;; set --
esac fi
### ###
@ -91,6 +132,7 @@ function update_with_rsync() {
} }
deps=() deps=()
modules=()
for m in "$@"; do for m in "$@"; do
m="${m#vendor/}" # pour permettre de spécifier le chemin directement m="${m#vendor/}" # pour permettre de spécifier le chemin directement
m="${m//\//-}" m="${m//\//-}"
@ -98,10 +140,19 @@ for m in "$@"; do
ur-*|lib-*) ;; ur-*|lib-*) ;;
*) m="ur-$m";; *) m="ur-$m";;
esac esac
modules+=("$m")
p="${m//-/\/}" p="${m//-/\/}"
check_module check_module
case "$action" in case "$action" in
rsync)
# Action par défaut: ignorer les liens et synchroniser les copies
if [ ! -L "vendor/$p" ]; then
etitle "$m"
update_with_rsync
eend
fi
;;
link) link)
# Ignorer les liens et transformer les copies en liens # Ignorer les liens et transformer les copies en liens
if [ ! -L "vendor/$p" ]; then if [ ! -L "vendor/$p" ]; then
@ -153,7 +204,7 @@ for m in "$@"; do
array_add deps "$p" array_add deps "$p"
eend eend
;; ;;
update) update|update-commit|update-deps|update-recursive)
# Supprimer les liens et répertoires... # Supprimer les liens et répertoires...
etitle "$m" etitle "$m"
if [ -e "vendor/$p" ]; then if [ -e "vendor/$p" ]; then
@ -163,28 +214,70 @@ for m in "$@"; do
array_add deps "$p" array_add deps "$p"
eend eend
;; ;;
*) *) die "$action: action inconnue";;
# Action par défaut: ignorer les liens et synchroniser les copies
if [ ! -L "vendor/$p" ]; then
etitle "$m"
update_with_rsync
eend
fi
;;
esac esac
done done
case "$action" in case "$action" in
install|reinstall-link) install|reinstall-link)
# ... puis installer les dépendances # ... puis installer les dépendances
etitle "Installation des dépendances" estep "Installation des dépendances"
./composer.phar i "$scriptdir/dk" ci || die
eend
;; ;;
update) update|update-commit)
# ... puis mettre à jour les dépendances # ... puis mettre à jour les dépendances
etitle "Mise à jour des dépendances" estep "Mise à jour des dépendances"
./composer.phar u "${deps[@]}" "$scriptdir/dk" cu "${deps[@]}" || die
eend
if [ "$action" == update-commit ]; then
if [ -z "$nowait" ]; then
# laisser le temps à @$*! d'eclipse qui met à jour automatiquement le projet...
estep "Attendre 10 secondes avant git commit"
sleep 10
fi
estep "Enregistrement dans git"
pci -A "maj deps"
fi
;;
update-deps)
# mettre à jour les dépendances directes
for m in "${modules[@]}"; do
etitle "Mise à jour projet dépendant: $m"
"$script" -d "../$m" -w
eend
done
estep "Mise à jour des dépendances"
"$scriptdir/dk" cu || die
if [ -z "$nowait" ]; then
# laisser le temps à @$*! d'eclipse qui met à jour automatiquement le projet...
estep "Attendre 10 secondes avant git commit"
sleep 10
fi
estep "Enregistrement dans git"
pci -A "maj deps"
;;
update-recursive)
# mettre à jour les dépendances de façon récursive
for m in "${modules[@]}"; do
etitle "Mise à jour récursive: $m"
"$script" -d "../$m" --ur
eend
done
estep "Mise à jour des dépendances"
"$scriptdir/dk" cu || die
if [ -z "$nowait" ]; then
# laisser le temps à @$*! d'eclipse qui met à jour automatiquement le projet...
estep "Attendre 10 secondes avant git commit"
sleep 10
fi
estep "Enregistrement dans git"
pci -A "maj deps"
;; ;;
esac esac

1053
dk

File diff suppressed because it is too large Load Diff

116
dmctl Executable file
View File

@ -0,0 +1,116 @@
#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source /etc/ulibauto || exit 1
function display_help() {
uecho "$scriptname: import/exporter une docker-machine
USAGE
$scriptname -d NAME
$scriptname -l ARCHIVE
OPTIONS
-d, --dump
Exporter la machine
-l, --load
Import la machine"
}
action=
args=(
--help '$exit_with display_help'
-d,--dump,-x,--export,-s,--save action=dump
-l,--load,-i,--import action=load
)
parse_args "$@"; set -- "${args[@]}"
if [ -z "$action" ]; then
case "$1" in
d|dump|x|export|s|save) action=dump; shift;;
l|load|i|import) action=load; shift;;
*) die "Vous devez spécifier l'action à effectuer";;
esac
fi
case "$action" in
dump)
############################################################################
name="$1"
[ -n "$name" ] || die "Vous devez spécifier le nom de la machine"
srcdir="$HOME/.docker/machine/machines/$name"
[ -d "$srcdir" ] || die "$name: nom de machine incorrect"
ac_set_tmpdir workdir
destdir="$workdir/$name"
archive="${name}-machine.tar.gz"
estep "Copie des fichiers"
cp -r "$srcdir" "$workdir" || die
for i in ca-key.pem ca.pem key.pem cert.pem; do
[ -f "$destdir/$i" ] || {
cp "$HOME/.docker/machine/certs/$i" "$destdir" || die
}
done
estep "Correction des chemins"
sed -i "\
s|$HOME/.docker/machine|DOCKER_MACHINE_HOME|g
s|DOCKER_MACHINE_HOME/certs/|DOCKER_MACHINE_HOME/machines/$name/|g
" "$destdir/config.json" || die
estep "Génération de $archive"
tar czf "$archive" -C "$workdir" "$name" || die
ac_clean "$workdir"
;;
load)
############################################################################
archive="$1"
[ -n "$archive" ] || die "Vous devez spécifier l'archive à importer"
setx archivename=basename -- "$archive"
if [[ "$archivename" == *-machine.tar.gz ]]; then
name="${archivename%-machine.tar.gz}"
else
die "$archive: n'est pas une archive docker-machine"
fi
destdir="$HOME/.docker/machine/machines"
machinedir="$destdir/$name"
origdir="$HOME/${name}-machine.orig"
if [ -d "$machinedir" ]; then
ewarn "$name: une machine du même nom existe déjà"
ask_yesno "Voulez-vous l'écraser?" N || die
[ -d "$origdir" ] && rm -rf "$origdir"
mv "$machinedir" "$origdir"
fi
ac_set_tmpdir workdir
srcdir="$workdir/$name"
estep "Extraction de l'archive"
tar xzf "$archive" -C "$workdir"
[ -d "$srcdir" ] || die "L'archive n'est pas pour la machine $name"
estep "Corriger les chemins"
sed -i "\
s|DOCKER_MACHINE_HOME|$HOME/.docker/machine|g
" "$srcdir/config.json" || die
estep "Installation de la machine"
mkdir -p "$destdir"
mv "$srcdir" "$destdir"
if [ -d "$origdir" ]; then
enote "Une fois que la machine aura été testée, vous pouvez supprimer ce répertoire:
$origdir"
fi
ac_clean "$workdir"
;;
esac

122
ensure-vip Executable file
View File

@ -0,0 +1,122 @@
#!/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" || exit 1
urequire DEFAULTS ipcalc
function display_help() {
uecho "$scriptname: s'assurer que l'hôte courant a l'adresse IP spécifiée
USAGE
$scriptname IPs...
NB: ce script ne supporte que la modification d'interfaces qui ne sont pas des
bridges. il est conçu avant tout pour utilisation sur un serveur, pas un poste
de travail.
OPTIONS
-i, --ignore-iface IFACE
Ajouter une interface à la liste des interfaces à ignorer. Si cette
option est utilisée, la liste par défaut n'est pas utilisée, sauf si
l'option -d est utilisée aussi.
-d, --defaults
Ajouter les valeurs suivantes à liste des interfaces à ignorer:
${DEFAULT_IGNORE_IFACES[*]}
Cette option est automatiquement activée si l'option -i n'est pas
utilisée
-n, --fake
Afficher simplement les modification à effectuer"
}
DEFAULT_IGNORE_IFACES=(
"docker*"
"br-*"
"veth*"
)
DEFAULT_PROFILES=(prod test devel)
ignore_ifaces=()
fake=
args=(
--help '$exit_with display_help'
-i:,--ignore-iface: ignore_ifaces
-d,--defaults '$array_extend ignore_ifaces DEFAULT_IGNORE_IFACES'
-n,--fake fake=1
)
parse_args "$@"; set -- "${args[@]}"
require_debian
for vip in "$@"; do
[ "${vip%/*}" != "$vip" ] || vip="$vip/32"
vips+=("$vip")
done
array_fix_paths ignore_ifaces
[ ${#ignore_ifaces[*]} -gt 0 ] || ignore_ifaces=("${DEFAULT_IGNORE_IFACES[@]}")
if [ -n "$fake" ]; then
set_verbosity --debug
__NETWORK_DEVEL_SHOW_MODIFS=1
__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS=1
fi
################################################################################
# réimplémentation "corrigée" de network_config_partial()
nifile="$__DEBIAN_NETWORK_INTERFACES"
network_set_confips
network_set_confbrs
tmpconfips=()
for confip in "${confips[@]}"; do
network_parse_confip "$confip" iface gateway ipsuffixes
continue=
for ignore_iface in "${ignore_ifaces[@]}"; do
if eval "[[ \"\$iface\" == $(qwc "$ignore_iface") ]]"; then
continue=1
break
fi
done
[ -n "$continue" ] && continue
tmpconfips+=("$confip")
network_parse_ipsuffix "${ipsuffixes[0]}" mainip suffix
for vip in "${vips[@]}"; do
if [ "${vip%.*}" == "${mainip%.*}" ]; then
tmpconfips+=("$iface:$vip")
fi
done
done
confips=("${tmpconfips[@]}")
confbrs=()
network_fix_confs
network_config "" confips confbrs || exit 0
# des modifications ont eu lieu, tenter de configurer les nouvelles adresses
# d'abord calculer les adresses ips qui sont activées
network_set_confips
for confip in "${confips[@]}"; do
network_parse_confip "$confip" iface gateway ipsuffixes
for ipsuffix in "${ipsuffixes[@]}"; do
network_parse_ipsuffix "$ipsuffix" ip suffix
array_addu ips "$ip"
done
done
# puis lister les commandes correspondant aux adresses ips non activées
array_from_lines ups "$(awkrun <"$nifile" -f ips[@] '
$1 == "up" && $2 == "ip" && $3 == "addr" && $4 == "add" {
ip = $5; sub(/(\/[0-9.]+)?$/, "", ip) # enlever suffixe
if (! in_array(ip, ips)) {
$1 = ""
print
}
}')"
if [ ${#ups[*]} -gt 0 ]; then
etitle "Configuration des nouvelles adresses"
for up in "${ups[@]}"; do
estep "$up"
eval "$up"
done
eend
fi

View File

@ -87,7 +87,7 @@ OPTIONS
-C, --composer-projects -C, --composer-projects
Equivalent à '--ptitle -p */composer.json --' Equivalent à '--ptitle -p */composer.json --'
--cc, --composer-cmd --cc, --composer-cmd
Equivalent à '--ptitle -p */composer.phar -- ./composer.phar'" Equivalent à '--ptitle -p */composer.json -- dk composer'"
} }
basedir= basedir=
@ -129,7 +129,7 @@ composer)
[ "$title" == auto ] && title=p [ "$title" == auto ] && title=p
;; ;;
composer-cmd) composer-cmd)
set -- */composer.phar -- ./composer.phar "$@" set -- */composer.json -- "$scriptdir/dk" composer "$@"
parentdir=1 parentdir=1
[ "$title" == auto ] && title=p [ "$title" == auto ] && title=p
;; ;;

View File

@ -0,0 +1,13 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
if [ -n "$UTOOLS_DOCKER_ALIASES" ]; then
if [ "$DOCKER_MACHINE_WRAPPED" == true ]; then
alias dm=__docker_machine_wrapper
else
alias dm=docker-machine
fi
if [ -n "$UTOOLS_BASH_COMPLETION" ]; then
complete -F _docker_machine dm
fi
fi

View File

@ -14,3 +14,6 @@
# _root. Par défaut, ce n'est le cas que si sudo n'est pas installé. Si sudo est # _root. Par défaut, ce n'est le cas que si sudo n'est pas installé. Si sudo est
# configuré, il est préférable de ne pas utiliser su. # configuré, il est préférable de ne pas utiliser su.
#export UTOOLS_USES_SU=false #export UTOOLS_USES_SU=false
# Activer les aliases pour l'utilisation de docker
#export UTOOLS_DOCKER_ALIASES=1

View File

@ -5,3 +5,6 @@
# Profiles pour docker-machine # Profiles pour docker-machine
#DM_PROFILES=(name:profile...) #DM_PROFILES=(name:profile...)
# Image à utiliser pour lancer composer
#COMPOSER_IMAGE=docker.univ-reunion.fr/image/utils-icmycas-php-apache:d9

View File

@ -1,18 +1,21 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
# Liste de préfixes permettant de taper le nom d'un dépôt plus rapidement e.g # Liste de préfixes permettant de taper le nom d'un dépôt plus rapidement e.g
# pcrone g/ssi-php/myproj # repoctl create g/ssi-php/myproj
# pcrone v:modules/myproj # repoctl create v:modules/myproj
# sont équivalents à # sont équivalents à
# pcrone https://git.univ-reunion.fr/ssi-php/myproj # repoctl create https://git.univ-reunion.fr/ssi-php/myproj
# pcrone git@vcs.univ.run:modules/myproj # repoctl create git@vcs.univ.run:modules/myproj
# Ces définitions fonctionnent aussi pour pclone
# Le format est ALIAS=ACTUAL # Le format est ALIAS=ACTUAL
#
# Ces définitions fonctionnent aussi pour tous les scripts qui utilisent
# repoctl, dont notamment pclone et pcrone
REPO_PREFIXES=( REPO_PREFIXES=(
s:=git@git.univ-reunion.fr: s:=git@git.univ-reunion.fr:
g/=https://git.univ-reunion.fr/ g/=https://git.univ-reunion.fr/
v:=git@vcs.univ.run: av/=https://vcs.univ-reunion.fr/anongit/ v:=git@vcs.univ.run: av/=https://vcs.univ-reunion.fr/anongit/
p:=pgit@vcs.univ.run: ap/=https://pvcs.univ-reunion.fr/anongit/ p:=pgit@vcs.univ.run: ap/=https://pvcs.univ-reunion.fr/anongit/
j/=https://git.jclain.fr/
) )
# Définitions des types de dépôt. Le format est NAME:TYPE:PREFIX # Définitions des types de dépôt. Le format est NAME:TYPE:PREFIX
@ -21,6 +24,7 @@ REPO_PREFIXES=(
# type par défaut est 'gitolite' # type par défaut est 'gitolite'
REPO_TYPES=( REPO_TYPES=(
ur:gitea:https://git.univ-reunion.fr/ ur:gitea:https://git.univ-reunion.fr/
jclain:gitea:https://git.jclain.fr/
) )
# Configuration de l'accès à l'API gogs # Configuration de l'accès à l'API gogs

View File

@ -77,6 +77,7 @@ def run_umail():
('a:', 'attach=', "Attacher un fichier"), ('a:', 'attach=', "Attacher un fichier"),
('t:', 'content-type=', "Spécifier le type de contenu du fichier"), ('t:', 'content-type=', "Spécifier le type de contenu du fichier"),
('f:', 'body=', "Spécifier un fichier contenant le corps du message"), ('f:', 'body=', "Spécifier un fichier contenant le corps du message"),
(None, 'html', "Indiquer que le corps du message est du type text/html. Par défaut, il s'agit de text/plain"),
(None, 'gencmd', "Générer une commande à évaluer pour envoyer le mail"), (None, 'gencmd', "Générer une commande à évaluer pour envoyer le mail"),
]) ])
options, args = get_args(None, options, longoptions) options, args = get_args(None, options, longoptions)
@ -87,6 +88,7 @@ def run_umail():
mbccs = [] mbccs = []
body = None body = None
bodyfile = None bodyfile = None
bodymtype = 'plain'
afiles = [] afiles = []
amimetypes = [] amimetypes = []
gencmd = False gencmd = False
@ -110,6 +112,8 @@ def run_umail():
bodyfile = None bodyfile = None
elif not path.exists(bodyfile): elif not path.exists(bodyfile):
die("%s: fichier introuvable" % bodyfile) die("%s: fichier introuvable" % bodyfile)
elif option in ('--html',):
bodymtype = 'html'
elif option in ('--gencmd',): elif option in ('--gencmd',):
gencmd = True gencmd = True
@ -133,14 +137,14 @@ def run_umail():
if not afiles: if not afiles:
# Sans attachement, faire un message simple # Sans attachement, faire un message simple
msg = MIMEText('\n'.join(lines), 'plain') msg = MIMEText('\n'.join(lines), bodymtype)
msg.set_charset('utf-8') msg.set_charset('utf-8')
else: else:
# Il y a des attachement, faire un multipart # Il y a des attachement, faire un multipart
msg = MIMEMultipart() msg = MIMEMultipart()
#msg.set_charset('utf-8') #msg.set_charset('utf-8')
if lines: if lines:
body = MIMEText('\n'.join(lines), 'plain') body = MIMEText('\n'.join(lines), bodymtype)
body.set_charset('utf-8') body.set_charset('utf-8')
msg.attach(body) msg.attach(body)
i = 0 i = 0

48
lib/repoctl/json_build.php Executable file
View File

@ -0,0 +1,48 @@
#!/usr/bin/php
<?php # -*- coding: utf-8 mode: php -*- vim:sw=2:sts=2:et:ai:si:sta:fenc=utf-8
function fix_value($value) {
if ($value === "true") return true;
elseif ($value === "false") return false;
elseif ($value === "null") return null;
else return $value;
}
function setp(&$array, $keys, $value) {
if (is_array($keys)) $keys = implode(".", $keys);
$keys = explode(".", $keys);
$last = count($keys) - 1;
$i = 0;
if ($array === null) $array = array();
$current =& $array;
foreach ($keys as $key) {
if ($i == $last) break;
if (!array_key_exists($key, $current)) $current[$key] = array();
if (!is_array($current[$key])) $current[$key] = array($current[$key]);
$current =& $current[$key];
$i++;
}
if ($key === "") {
$current[] = $value;
} else {
$current[$key] = $value;
}
}
$data = array();
$empty = true;
for ($i = 1; $i < $argc; $i++) {
$namevalue = $argv[$i];
if (preg_match('/(.*?)=(.*)/', $namevalue, $ms)) {
$name = $ms[1];
$value = fix_value($ms[2]);
setp($data, $name, $value);
} else {
$value = fix_value($namevalue);
$data[] = $value;
}
$empty = false;
}
$options = JSON_NUMERIC_CHECK;
if ($empty) $options += JSON_FORCE_OBJECT;
echo json_encode($data, $options);

28
lib/repoctl/json_each.php Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/php
<?php # -*- coding: utf-8 mode: php -*- vim:sw=2:sts=2:et:ai:si:sta:fenc=utf-8
if ($argc <= 1) die("ERROR: Vous devez spécifier le nom de la clé\n");
$data = json_decode(stream_get_contents(STDIN), true);
foreach ($data as $datum) {
$first = true;
for ($i = 1; $i < $argc; $i++) {
$result = $datum;
$keys = explode(".", trim($argv[$i]));
foreach ($keys as $key) {
if ($result === null) break;
if (!$key) continue;
if (isset($result[$key])) {
$result = $result[$key];
} else {
$result = null;
}
}
if ($first) $first = false;
else echo "\t";
if (is_array($result)) var_export($result);
else echo $result;
}
echo "\n";
}

27
lib/repoctl/json_get.php Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/php
<?php # -*- coding: utf-8 mode: php -*- vim:sw=2:sts=2:et:ai:si:sta:fenc=utf-8
if ($argc <= 1) die("ERROR: Vous devez spécifier le nom de la clé\n");
$datum = json_decode(stream_get_contents(STDIN), true);
$first = true;
for ($i = 1; $i < $argc; $i++) {
$result = $datum;
$keys = explode(".", trim($argv[$i]));
foreach ($keys as $key) {
if ($result === null) break;
if (!$key) continue;
if (isset($result[$key])) {
$result = $result[$key];
} else {
$result = null;
}
}
if ($first) $first = false;
else echo "\t";
if (is_array($result)) var_export($result);
else echo $result;
}
echo "\n";

301
lib/ulib/pff Normal file
View File

@ -0,0 +1,301 @@
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
urequire multiconf
PFF_ORIGEXT=pff
PFF_CONF=.pff.conf # ne pas modifier
DEFAULT_PFF_ORIGEXTS=(".$ORIGEXT" .origine .default)
DEFAULT_PFF_PROTECTS=(/.git/ .svn/ /pff/ "/$PFF_CONF")
PFF_CONFVARS=(
"VERSION//Version actuellement installée"
-a
"PVERSIONS//Versions en attente d'intégration"
"PROFILES//Profils définis"
-s
"DISTTYPE=auto//Type de distribution upstream: full ou patch"
-a
"ORIGEXTS=//Extensions origines"
"PROTECTS=//Fichiers locaux à protéger lors de l'intégration e.g /dir/, /file, etc."
"MKDIRS//Répertoires qui doivent toujours exister"
"FILTERS//Filtres appliqués aux fichiers lors de l'intégration"
"NOMERGES=//Fichiers qu'il ne faut pas chercher à fusionner"
)
# Nomenclature pour le nommage des fichiers traités:
# pfile: le chemin absolu du fichier dans le projet
# rfile: le chemin relatif du fichier dans le projet
# bfile: le chemin absolu du fichier dans pff/Base/
# Cfile: le chemin absolu du fichier dans pff/Common/
# cfile: le chemin absolu du fichier dans pff/Current/
# Pfile: le chemin absolu du fichier dans pff/ANYPROFILE/
# plink: la destination du lien pfile
# clink: la destination du lien cfile
# Plink: la destination du lien Pfile
function flexists() {
[ -e "$1" -o -L "$1" ]
}
function multiups() {
# afficher un chemin vers le haut e.g ../../.. avec autant d'éléments que
# les répertoires du chemin relatif $1.
# méthode: commencer avec la valeur de départ $2 et préfixer avec autant de
# ../ que nécessaire. puis afficher le résultat.
local tmp="$1" link="$2"
setx tmp=dirname -- "$tmp"
while [ "$tmp" != . ]; do
[ -n "$link" ] && link="/$link"
link="..$link"
setx tmp=dirname -- "$tmp"
done
echo "$link"
}
function find_pffdir() {
# trouver le répertoire du projet pff à partir du répertoire $2(=.) et
# mettre le chemin absolu dans la variable $1(=pffdir)
# si le répertoire n'est pas trouvé, retourner 1
local destvar="${1:-pffdir}" pffdir
setx pffdir=abspath "${2:-.}"
while true; do
if [ -f "$pffdir/$PFF_CONF" -a -d "$pffdir/pff" ]; then
local "$destvar"
upvar "$destvar" "$pffdir"
return 0
fi
[ "$pffdir" == / -o "$pffdir" == "$HOME" ] && break
setx pffdir=dirname -- "$pffdir"
done
return 1
}
function ensure_pffdir() {
# trouver le répertoire du projet pff à partir du répertoire $2(=.) et
# mettre le chemin absolu dans la variable $1(=pffdir)
# si le répertoire n'est pas trouvé, arrêter le script avec un code d'erreur
local destvar="${1:-pffdir}" pffdir
if find_pffdir pffdir "$2"; then
conf_init "${PFF_CONFVARS[@]}"
source "$pffdir/$PFF_CONF"
local "$destvar"; upvar "$destvar" "$pffdir"
return
fi
local msg="Projet pff introuvable (utiliser --init ?)"
[ -n "$2" ] && die "$2: $msg" || die "$msg"
}
function pff_get_current_profile() {
# afficher le profil courant du projet pff $1, s'il est défini
local pffdir="$1"
[ -L "$pffdir/pff/.Current" ] && readlink "$pffdir/pff/.Current"
}
function pff_get_profiles() {
# afficher tous les profils valides du projet pff $1
local pffdir="$1"
(for profile in "${PROFILES[@]}"; do echo "$profile"; done
list_dirs "$pffdir/pff") | sort -u | grep -vxF Current
}
function pff_get_user_profiles() {
# afficher tous les profils modifiables du projet pff $1 (c'est à dire tous
# les profils valides excepté Base)
pff_get_profiles "$@" | grep -vxF Base
}
function pff_get_first_profile() {
# afficher le premier profil autre que Base du projet pff $1
local profile
profile="${PROFILES[0]}"
if [ -z "$profile" -o "$profile" == Base ]; then
pff_get_user_profiles "$@" | head -n1
else
echo "$profile"
fi
}
function pff_get_local_files() {
# afficher tous les fichiers locaux exprimés relativement au répertoire du
# projet pff $1
local pffdir="$1"
find "$pffdir/pff/Base" -type f | sed "s|^$pffdir/pff/Base/||" | grep -v '__pv-.*__$'
}
function pff_get_rfile() {
# obtenir le chemin relatif du fichier $1 exprimé par rapport au répertoire
# du projet pff $2. Si c'est un fichier d'un répertoire de profil,
# l'exprimer comme un chemin du répertoire de projet, e.g pff/Profile/path
# devient path
# retourner 1 si le chemin est invalide (est situé en dehors de pffdir ou
# pas dans un répertoire de profil)
local rfile="$1" pffdir="$2"
setx rfile=abspath "$rfile"
[ "${rfile#$pffdir/}" != "$rfile" ] || return 1
rfile="${rfile#$pffdir/}"
if [[ "$rfile" == pff/*/* ]]; then
rfile="${rfile#pff/*/}"
elif [[ "$rfile" == pff/* ]]; then
return 1
fi
echo "$rfile"
}
function pff_get_pfile() {
# obtenir le chemin du fichier $1 exprimé par rapport au répertoire du
# profil $2 dans le répertoire de projet $3
# retourner 1 si le chemin est invalide (est situé en dehors de pffdir ou
# pas dans un répertoire de profil)
local pfile="$1" profile="$2" pffdir="$3"
setx pfile=abspath "$pfile"
[ "${pfile#$pffdir/}" != "$pfile" ] || return 1
pfile="${pfile#$pffdir/}"
if [[ "$pfile" == pff/*/* ]]; then
pfile="${pfile#pff/*/}"
elif [[ "$pfile" == pff/* ]]; then
return 1
fi
echo "$pffdir/pff/$profile/$pfile"
}
function pff_get_bfile() { pff_get_pfile "$1" Base "$2"; }
function pff_get_Cfile() { pff_get_pfile "$1" Common "$2"; }
function pff_get_cfile() { pff_get_pfile "$1" Current "$2"; }
function pff_get_vlfiles_nostrip() {
# afficher tous les fichiers de version
local pffdir="$1" rfile="$2" profile="${3:-Base}" version="$4"
[ -d "$pffdir/pff/$profile" ] || return
if [ -n "$version" ]; then
if [ -n "$rfile" ]; then
find "$pffdir/pff/$profile" \
-type f -path "$pffdir/pff/$profile/${rfile}__pv-${version}__" -o \
-type l -path "$pffdir/pff/$profile/${rfile}__pv-${version}__"
else
find "$pffdir/pff/$profile" \
-type f -name "*__pv-${version}__" -o \
-type l -name "*__pv-${version}__"
fi
else
if [ -n "$rfile" ]; then
find "$pffdir/pff/$profile" \
-type f -path "$pffdir/pff/$profile/${rfile}__pv-*__" -o \
-type l -path "$pffdir/pff/$profile/${rfile}__pv-*__"
else
find "$pffdir/pff/$profile" \
-type f -name "*__pv-*__" -o \
-type l -name "*__pv-*__"
fi
fi
}
function pff_get_vlfiles() {
local pffdir="$1" rfile="$2" profile="${3:-Base}" version="$4"
pff_get_vlfiles_nostrip "$@" | sed "s|^$pffdir/pff/$profile/||"
}
function pff_is_nomerge() {
local file="$1" pffdir="$2"
local nomerge rfile
setx rfile=pff_get_rfile "$file" "$pffdir"
setx file=basename -- "$rfile" # utilisé pour le match sur le nom du fichier
for nomerge in "${NOMERGES[@]}"; do
if [[ "$nomerge" == */* ]]; then
# matcher sur le chemin relatif
if eval "[[ $(qval "$rfile") == $(qwc "$nomerge") ]]"; then
return 0
fi
else
# matcher uniquement sur le nom du fichier
if eval "[[ $(qval "$file") == $(qwc "$nomerge") ]]"; then
return 0
fi
fi
done
return 1
}
function pff_sync_vlfiles() {
# synchroniser les fichiers de version $3..@ dans tous les répertoires de
# profil, ou seulement le répertoire de profil $2 si la valeur n'est pas
# vide.
local pffdir="$1"; shift
local profile="$1"; shift
local -a profiles
if [ -n "$profile" ]; then
profiles=("$profile")
else
array_from_lines profiles "$(pff_get_user_profiles "$pffdir")"
fi
local vlfile rfile prefix pfile plink tmp
for vlfile in "$@"; do
rfile="${vlfile%__pv-*__}"
for profile in "${profiles[@]}"; do
prefix="$pffdir/pff/$profile"
flexists "$prefix/$rfile" || continue
pfile="$prefix/$vlfile"
setx plink=multiups "$profile/$vlfile" "Base/$vlfile"
if [ -L "$pfile" ]; then
# correction éventuelle du lien existant
setx tmp=readlink "$pfile"
[ "$tmp" == "$plink" ] || ln -sfT "$plink" "$pfile"
else
ln -sf "$plink" "$pfile" || return
fi
done
done
}
function pff_select_profile() {
# sélectionner le profil $1 dans le projet pff $2. créer d'abord le profil
# s'il n'existe pas.
local profile="$1" pffdir="$2"
# créer le répertoire de profil si nécessaire
mkdir -p "$pffdir/pff/$profile" || return 1
# mettre à jour les liens
local -a lfiles; local lfile src dest
setx -a lfiles=pff_get_local_files "$pffdir"
for lfile in "${lfiles[@]}"; do
src="$pffdir/pff/Current/$lfile"
if [ -f "$pffdir/pff/$profile/$lfile" ]; then
dest="$profile/$lfile"
elif [ "$profile" != Common -a -f "$pffdir/pff/Common/$lfile" ]; then
dest="Common/$lfile"
else
dest="Base/$lfile"
fi
setx dest=multiups "Current/$lfile" "$dest"
[ -L "$src" ] || mkdirof "$src"
ln -sfT "$dest" "$src"
done
# maj du lien "profil courant"
ln -sfT "$profile" "$pffdir/pff/.Current"
}
function pff_autoinit() {
# vérifications automatiques: créer les répertoires de base nécessaire au
# fonctionnement de pff dans le projet pff $1
local pffdir="$1" profile mkdir
[ -d "$pffdir/pff/Current" ] || mkdir -p "$pffdir/pff/Current"
[ -d "$pffdir/pff/Base" ] || mkdir -p "$pffdir/pff/Base"
# tous les fichiers du profil Base doivent être en lecture seule
find "$pffdir/pff/Base" -type f -perm /222 -exec chmod a-w '{}' +
# Créer les répertoires de MKDIRS
for mkdir in "${MKDIRS[@]}"; do
mkdir -p "$pffdir/$mkdir"
done
return 0
}
function pff_autoselect() {
# vérification automatiques: sélectionner le premier profil défini si aucun
# profil n'est sélectionné dans le projet pff $1
local pffdir="$1" profile
if [ ! -L "$pffdir/pff/.Current" ]; then
setx profile=pff_get_first_profile "$pffdir"
[ -n "$profile" ] || profile=Base
enote "Autosélection du profil $profile"
pff_select_profile "$profile" "$pffdir"
fi
}
function pff_autofix() {
pff_autoinit "$1"
pff_autoselect "$1"
}

94
pff
View File

@ -26,10 +26,10 @@ PFFCONFVARS=(
"DISTTYPE=auto//Type de distribution upstream: full ou patch" "DISTTYPE=auto//Type de distribution upstream: full ou patch"
-a -a
"ORIGEXTS=//Extensions origines" "ORIGEXTS=//Extensions origines"
"PROTECTS=//Fichiers locaux à protéger lors de l'intégration e.g /dir/, /file, etc." "PROTECTS=//Fichiers locaux à protéger lors de l'intégration au format rsync e.g /dir/, /file, etc."
"MKDIRS//Répertoires qui doivent toujours exister" "MKDIRS//Répertoires qui doivent toujours exister"
"FILTERS//Filtres appliqués aux fichiers lors de l'intégration" "FILTERS//Filtres appliqués aux fichiers lors de l'intégration, de la forme 'filespec:filter'. Cf la doc pour le détail du format"
"NOMERGES=//Fichiers qu'il ne faut pas chercher à fusionner" "NOMERGES=//Fichiers qu'il ne faut pas chercher à fusionner. Cf la doc pour le détail du format"
) )
if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then if [ "$#" -eq 1 -a "$1" == --nutools-makelinks ]; then
@ -152,6 +152,44 @@ sont:
USAGE USAGE
$scriptname [options] $scriptname [options]
CONFIGURATION
Le fichier $PFFCONF contient des variables qui conditionnent le comportement de
pff:
PROTECTS -- liste de spécifications de fichiers ou de répertoires à protéger
lors de l'intégration. Ces spécifications sont au format rsync, e.g
/dir/, /file, etc.
FILTERS -- liste de définitions de filtres à appliquer aux fichiers lors de
l'intégration. ces spécifications sont de la forme 'filespec:filter'.
Les spécifications de fichier peuvent contenir des wildcards et sont de
deux sortes:
- sans chemin, e.g 'myfile' ou '*.c', tous les fichiers de ce nom
correspondent
- avec un chemin, e.g '/myfile', 'path/to/*.jsp', la correspondance est
cherchée relativement au répertoire du projet. ainsi '/*.c' ne matche
que les fichiers ayant l'extension .c situés dans le répertoire du
projet
Les filtres disponibles sont:
nl2lf -- forcer le caractère de fin de ligne à LF
nl2crlf -- forcer le caractère de fin de ligne à CR+LF
nl2cr -- forcer le caractère de fin de ligne à CR
normalize_properties -- normaliser fichier de propriétés java
Il est possible de créer de nouveaux filtres en définissant des
fonctions de la forme pff_filter_NAME(). Ces fonctions, si elles sont
appelées sans argument, doivent filtrer l'entrée standard. Si un
argument est spécifié, il faut filtrer ce fichier-là.
NOMERGES -- liste de spécifications de fichiers qu'il ne faut pas chercher à
fusionner. Les spécifications de fichier peuvent contenir des wildcards
et sont de deux sortes:
- sans chemin, e.g 'myfile' ou '*.c', tous les fichiers de ce nom
correspondent
- avec un chemin, e.g '/myfile', 'path/to/*.jsp', la correspondance est
cherchée relativement au répertoire du projet. ainsi '/*.c' ne matche
que les fichiers ayant l'extension .c situés dans le répertoire du
projet
COMMANDES / OPTIONS COMMANDES / OPTIONS
Les arguments du script dépendent de la commande utilisée. Les commandes Les arguments du script dépendent de la commande utilisée. Les commandes
supportées sont: supportées sont:
@ -456,6 +494,7 @@ function is_nomerge() {
for nomerge in "${NOMERGES[@]}"; do for nomerge in "${NOMERGES[@]}"; do
if [[ "$nomerge" == */* ]]; then if [[ "$nomerge" == */* ]]; then
# matcher sur le chemin relatif # matcher sur le chemin relatif
nomerge="${nomerge#/}"
if eval "[[ $(qval "$rfile") == $(qwc "$nomerge") ]]"; then if eval "[[ $(qval "$rfile") == $(qwc "$nomerge") ]]"; then
return 0 return 0
fi fi
@ -572,6 +611,39 @@ function pff_filter_normalize_properties() {
return $r return $r
fi fi
} }
function pff_filter_nl2lf() {
if [ $# -eq 0 ]; then
_nl2lf
else
local mode r
mode="$(fix_mode "$1")"
doinplace "$1" _nl2lf; r=$?
unfix_mode "$1" "$mode"
return $r
fi
}
function pff_filter_nl2crlf() {
if [ $# -eq 0 ]; then
_nl2crlf
else
local mode r
mode="$(fix_mode "$1")"
doinplace "$1" _nl2crlf; r=$?
unfix_mode "$1" "$mode"
return $r
fi
}
function pff_filter_nl2cr() {
if [ $# -eq 0 ]; then
_nl2cr
else
local mode r
mode="$(fix_mode "$1")"
doinplace "$1" _nl2cr; r=$?
unfix_mode "$1" "$mode"
return $r
fi
}
function apply_filter() { function apply_filter() {
# Appliquer les filtres définis au fichier $1 dans le projet pff $2 # Appliquer les filtres définis au fichier $1 dans le projet pff $2
@ -580,12 +652,22 @@ function apply_filter() {
# produite, 2 si aucun filtre n'existe pour ce fichier # produite, 2 si aucun filtre n'existe pour ce fichier
local pfile="$1" pffdir="$2" local pfile="$1" pffdir="$2"
local realfile="${3:-$pfile}" local realfile="${3:-$pfile}"
local rfile ffile filter r=2 local rfile ffile filter r=2 filedir filespec
setx rfile=get_rfile "$realfile" "$pffdir" setx rfile=get_rfile "$realfile" "$pffdir"
setx file=basename -- "$rfile" # utilisé pour le match sur le nom du fichier
for filter in "${FILTERS[@]}"; do for filter in "${FILTERS[@]}"; do
splitpair "$filter" ffile filter splitpair "$filter" ffile filter
if [ "$ffile" == "$rfile" ]; then if [[ "$ffile" == */* ]]; then
"pff_filter_$filter" "$pfile" && r=0 || r=1 # matcher sur le chemin relatif
ffile="${ffile#/}"
if eval "[[ $(qval "$rfile") == $(qwc "$ffile") ]]"; then
"pff_filter_$filter" "$pfile" && r=0 || r=1
fi
else
# matcher uniquement sur le nom du fichier
if eval "[[ $(qval "$file") == $(qwc "$ffile") ]]"; then
"pff_filter_$filter" "$pfile" && r=0 || r=1
fi
fi fi
done done
return $r return $r

332
repoctl Executable file
View File

@ -0,0 +1,332 @@
#!/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" || exit 1
urequire DEFAULTS
function display_help() {
uecho "$scriptname: piloter un serveur git (gitolite, gogs, gitea, etc.)
USAGE
$scriptname ACTION URL [options]
ACTIONS
create URL [description]
Créer un nouveau dépôt avec la description spécifiée
list URL [VARs...]
Lister les dépôts dans l'organisation spécifiée. Si aucune organisation
n'est spécifiée dans l'url, lister les dépôts *accessibles* par
l'utilisateur (cela inclut les dépôts des organisations auxquelles
l'utilisateur a accès)
VARs est une liste de variables à afficher pour chaque dépôt, séparés
par le caractère tabulation. La valeur par défaut est full_name
get URL [VARs...]
Afficher les propriétés du dépôt spécifié. VARs est une liste de
variables à afficher pour le dépôt, séparés par le caractère tabulation.
edit URL var=value...
Modifier les propriétés du dépôt. Consulter l'API pour la liste exacte
des propriétés pouvant être modifiées. Avec gitea 1.9.3, il y a au moins
celles-là:
name
description
website
private
default_branch
delete URL
Supprimer le dépôt spécifié"
}
function json_build() {
"$scriptdir/lib/repoctl/json_build.php" "$@"
}
function json_get() {
"$scriptdir/lib/repoctl/json_get.php" "$@"
}
function json_each() {
"$scriptdir/lib/repoctl/json_each.php" "$@"
}
function repoctl_init() {
repourl="${1%.git}"
[ -n "$repourl" ] || return
rname=
rtype=gitolite
rprefix=
REPO_PREFIXES=()
REPO_TYPES=()
set_defaults repoctl
# Traduire les aliases éventuels
local asrcdest asrc adest
for asrcdest in "${REPO_PREFIXES[@]}"; do
splitfsep "$asrcdest" = asrc adest
if [ "${repourl#$asrc}" != "$repourl" ]; then
newurl="$adest${repourl#$asrc}"
if [ "$newurl" != "$repourl" ]; then
enote "$repourl --> $newurl"
repourl="$newurl"
break
fi
fi
done
local rnametypeprefix tmp found
for rnametypeprefix in "${REPO_TYPES[@]}"; do
splitfsep "$rnametypeprefix" : rname tmp
splitfsep "$tmp" : rtype rprefix
if [ "${repourl#$rprefix}" != "$repourl" ]; then
found=1
break
fi
done
if [ -z "$found" ]; then
rname=
rtype=gitolite
rprefix=
fi
}
function curlto() {
local url="$1"; shift
local payload="$1"; shift
local outfile="$1"; shift
local tmpfile
if [ -z "$outfile" ]; then
ac_set_tmpfile tmpfile
outfile="$tmpfile"
fi
local -a args
local r http_code
args=(-s -w '%{http_code}' -o "$outfile")
[ -n "$payload" ] && args+=(-d "$payload")
[ -n "$HTTP_METHOD" ] && args+=(-X "$HTTP_METHOD")
args+=("$@" "$url")
setx http_code=curl "${args[@]}"
case "$http_code" in
2*) r=0;;
4*) r=1;;
5*) r=3;;
*) r=11;;
esac
if [ -n "$tmpfile" ]; then
cat "$tmpfile"
ac_clean "$tmpfile"
fi
upvar http_code "$http_code"
return "$r"
}
function gogs_setvars() {
gogs_url="${rname}_GOGS_URL"; gogs_url="${!gogs_url}"
gogs_user="${rname}_GOGS_USER"; gogs_user="${!gogs_user}"
gogs_key="${rname}_GOGS_KEY"; gogs_key="${!gogs_key}"
userpath="${repourl#$rprefix}"
splitfsep "$userpath" / user path
}
################################################################################
function create_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_create_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_create_action() {
local url repourl desc payload result
local -a vars
if [ -n "$user" -a "$user" != "$gogs_user" ]; then
# créer un dépôt dans une organisation
url="$gogs_url/api/v1/org/$user/repos"
repourl="$gogs_url/$user/$path"
else
# créer un dépôt pour un utilisateur
url="$gogs_url/api/v1/user/repos"
repourl="$gogs_url/$gogs_user/$path"
fi
vars=(name="$path" private=true)
[ -n "$1" ] && vars+=(description="$1"); shift
setx payload=json_build "${vars[@]}"
[ $# -gt 0 ] && vars=("$@") || vars=("")
setx result=curlto "$url" "$payload" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de création du dépôt
url: $url
payload: $payload
result: $result"
isatty && estep "Création du dépôt $repourl"
echo "$result" | json_get "${vars[@]}"
}
################################################################################
function list_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_list_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_list_action() {
local url result
local -a vars
if [ -n "$user" -a "$user" != "$gogs_user" ]; then
# lister les dépôts d'une organisation
url="$gogs_url/api/v1/orgs/$user/repos"
else
# lister les dépôts accessibles par l'utilisateur
url="$gogs_url/api/v1/user/repos"
fi
[ $# -gt 0 ] && vars=("$@") || vars=(full_name)
setx result=curlto "$url" "" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de listage des dépôts
url: $url
result: $result"
echo "$result" | json_each "${vars[@]}"
}
################################################################################
function get_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_get_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_get_action() {
local url repourl payload result
local -a vars
url="$gogs_url/api/v1/repos/$user/$path"
repourl="$gogs_url/$user/$path"
[ $# -gt 0 ] && vars=("$@") || vars=("")
local HTTP_METHOD=GET
setx result=curlto "$url" "" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de déplacement du dépôt
url: $url
payload: $payload
result: $result"
isatty && estep "Attributs du dépôt $repourl"
echo "$result" | json_get "${vars[@]}"
}
################################################################################
function edit_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_edit_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_edit_action() {
local url repourl payload result
local -a vars
url="$gogs_url/api/v1/repos/$user/$path"
repourl="$gogs_url/$user/$path"
vars=()
while [[ "$1" == *=* ]]; do
vars+=("$1")
shift
done
setx payload=json_build "${vars[@]}"
[ $# -gt 0 ] && vars=("$@") || vars=("")
local HTTP_METHOD=PATCH
setx result=curlto "$url" "$payload" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de déplacement du dépôt
url: $url
payload: $payload
result: $result"
isatty && estep "Mise à jour du dépôt $repourl"
echo "$result" | json_get "${vars[@]}"
}
################################################################################
function delete_action() {
case "$rtype" in
#gitolite) ;;
gogs|gitea)
gogs_setvars
gogs_delete_action "$@"
;;
*) die "$rtype: type de dépôt non supporté";;
esac
}
function gogs_delete_action() {
local url repourl payload result
url="$gogs_url/api/v1/repos/$user/$path"
repourl="$gogs_url/$user/$path"
local HTTP_METHOD=DELETE
setx result=curlto "$url" "" "" \
-H 'Content-Type: application/json' \
-H "Authorization: token $gogs_key" || \
die "Une erreur s'est produite lors de la tentative de suppression du dépôt
url: $url
payload: $payload
result: $result"
isatty && estep "Suppression du dépôt $repourl"
[ -n "$result" ] && echo "$result"
return 0
}
################################################################################
action=
args=(
--help '$exit_with display_help'
-c,--create action=create
-l,--list action=list
-g,--get action=get
-e,--edit action=edit
-d,--delete action=delete
)
parse_args "$@"; set -- "${args[@]}"
if [ -z "$action" ]; then
action="$1"; shift
fi
[ -n "$action" ] || action=list
repoctl_init "$1"; shift
[ -n "$repourl" ] || die "Vous devez spécifier l'url du dépôt"
case "$action" in
c|create) create_action "$@";;
l|list) list_action "$@";;
g|get|s|show) get_action "$@";;
e|edit) edit_action "$@";;
d|del|delete|rm|remove) delete_action "$@";;
esac

4
sqlcsv
View File

@ -1159,7 +1159,7 @@ public class sqlcsv {
int i = 0, max = args.length; int i = 0, max = args.length;
while (i < max) { while (i < max) {
String arg = args[i]; String arg = args[i];
if (arg.substring(0, 2).equals("-J") || arg.substring(0, 2).equals("+J")) { if (arg.length() >= 2 && (arg.substring(0, 2).equals("-J") || arg.substring(0, 2).equals("+J"))) {
die("L'option -J doit être spécifiée en premier", null); die("L'option -J doit être spécifiée en premier", null);
} else if (arg.equals("-C") || arg.equals("--config")) { } else if (arg.equals("-C") || arg.equals("--config")) {
config = getArg(args, ++i, "Vous devez spécifier le fichier de configuration"); config = getArg(args, ++i, "Vous devez spécifier le fichier de configuration");
@ -1316,7 +1316,7 @@ public class sqlcsv {
if (resetPrefs) throw new Exit(); if (resetPrefs) throw new Exit();
else throw new Exit("Vous devez spécifier l'url de connexion"); else throw new Exit("Vous devez spécifier l'url de connexion");
} }
if (usePrefs) { if (usePrefs && connid != null) {
log.fine("Enregistrement de la valeur connid=" + connid); log.fine("Enregistrement de la valeur connid=" + connid);
prefs.put("lastConnid", connid); prefs.put("lastConnid", connid);
} }

View File

@ -250,7 +250,7 @@ function cxone_init() {
REPO_PREFIXES=() REPO_PREFIXES=()
REPO_TYPES=() REPO_TYPES=()
set_defaults pcrone set_defaults repoctl
# Traduire les aliases éventuels # Traduire les aliases éventuels
local asrcdest asrc adest local asrcdest asrc adest

View File

@ -202,7 +202,7 @@ Les lignes commençant par # sont des commentaires et sont ignorées
0 1 * * * 0 1 * * *
osvar FIRST=default SECOND osvar FIRST=default SECOND
echo \"first is $FIRST and second is $SECOND\" echo \"first is \$FIRST and second is \$SECOND\"
En temps normal, FIRST vaut la valeur par défaut 'default' et SECOND vaut la En temps normal, FIRST vaut la valeur par défaut 'default' et SECOND vaut la
chaine vide ''. Si on appelle '$scriptname -v FIRST=1 -v SECOND=2' alors ces chaine vide ''. Si on appelle '$scriptname -v FIRST=1 -v SECOND=2' alors ces

90
woclean-logs Executable file
View File

@ -0,0 +1,90 @@
#!/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" || exit 1
urequire DEFAULTS
function display_help() {
uecho "$scriptname: supprimer les fichiers de log inutiles dans /var/log/WebObjects
USAGE
$scriptname [options]
OPTIONS
-u, --useless
Supprimer les logs inutiles. C'est l'option par défaut
-a, --all
Supprimer tous les logs
-t, --today
Supprimer tous les logs du jour"
}
what=useless
args=(
--help '$exit_with display_help'
-u,--useless what=useless
-a,--all what=all
-t,--today what=today
)
parse_args "$@"; set -- "${args[@]}"
run_as_root "$@"
count=0
cd /var/log/WebObjects || die
case "$what" in
useless)
einfo "Suppression des fichiers de log inutiles dans /var/log/WebObjects"
ask_yesno "Voulez-vous continuer?" O || exit
/bin/ls | while read f; do
[ "${f%-[0-9]}" != "$f" ] && continue
# Tester la presence de "Waiting for requests..."
if ! grep -q 'Waiting for requests...$' "$f"; then
echo "$f: no 'Waiting for Requests...'"
/bin/rm -f "$f" || die
count=$(($count + 1))
continue
fi
# Tester la presence de contenu apres Waiting for requests..."
if grep -v "CookieParser: Found a null cookie value in: " "$f" | tail -n 1 | grep -q 'Waiting for requests...$'; then
echo "$f: empty log"
/bin/rm -f "$f" || die
count=$(($count + 1))
continue
fi
done
;;
all)
einfo "Suppression de TOUS les fichiers de logs dans /var/log/WebObjects"
ask_yesno "Voulez-vous continuer?" O || exit
/bin/ls | while read f; do
if [ "${f%-[0-9]}" = "$f" ]; then
echo "$f"
/bin/rm -f "$f" || exit 1
count=$(($count + 1))
fi
done
;;
today)
einfo "Suppression des fichiers de logs DU JOUR dans /var/log/WebObjects"
ask_yesno "Voulez-vous continuer?" O || exit
now="$(date +%Y%m%d)"
/bin/ls | grep -- "-[0-9]*\\.$now[0-9]*$" | while read f; do
echo "$f"
/bin/rm -f "$f" || exit 1
count=$(($count + 1))
done
;;
esac
if [ $count -gt 0 ]; then
enote "$count fichiers supprimés"
fi