##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 ## Gestion des informations sur l'hôte local ##@cooked nocomments ##@require base uprovide sysinfos urequire base ################################################################################ ## Informations sur le système local ## type de système # attention: dans SYSNAMES et *_SYSDISTS, les noms doivent être ordonnés du # moins spécifique au plus spécifique SYSNAMES=(linux linux64 linux32 linuxppc64 linuxppc32 linuxarm macosx) linux_SYSDISTS=(debianlike debian ubuntu redhatlike ol rhel fedora centos suse gentoo) linux32_SYSDISTS=(debianlike debian ubuntu redhatlike ol rhel fedora centos suse gentoo) linux64_SYSDISTS=(debianlike debian ubuntu redhatlike ol rhel fedora centos suse gentoo) linuxppc32_SYSDISTS=(debianlike debian ubuntu redhatlike fedora) linuxppc64_SYSDISTS=(debianlike debian ubuntu redhatlike fedora) linuxarm_SYSDISTS=(debianlike debian ubuntu) macosx_SYSDISTS=(lion snowleopard leopard tiger panther) SYSDIST_ALIASES=( 10.7=lion 10.6=snowleopard 10.5=leopard 10.4=tiger 10.3=panther ) # attention: dans *_SYSVERS, les noms doivent être ordonnés du plus récent au # moins récent debianlike_SYSVERS=() debian_SYSVERS=(stretch jessie wheezy squeeze lenny etch) ubuntu_SYSVERS=(oneiric natty maverick lucid karmic jaunty intrepid hardy) redhatlike_SYSVERS=() ol_SYSVERS=(ol7 ol6 redhat7 redhat6) rhel_SYSVERS=(rhel7 rhel6 rhel5 rhel4 redhat7 redhat6 redhat5 redhat4) fedora_SYSVERS=(fedora14 fedora13 fedora12 fedora11) centos_SYSVERS=(centos7 centos6 centos5 centos4 redhat7 redhat6 redhat5 redhat4) suse_SYSVERS=() gentoo_SYSVERS=() SYSVER_ALIASES=( 9=stretch 8=jessie 7=wheezy 6=squeeze 5=lenny 4=etch 11.10=oneiric 11.04=natty 10.10=maverick 10.04=lucid 9.10=karmic 9.04=jaunty 8.10=intrepid 8.04=hardy ) function __setup_ALL_SYSvars() { local s ds d fs f ALL_SYSDISTS=() for s in "${SYSNAMES[@]}"; do array_copy ds "${s}_SYSDISTS" for d in "${ds[@]}"; do array_set ALL_SYSDISTS "$d" done done ALL_SYSVERS=() for d in "${ALL_SYSDISTS[@]}"; do array_copy fs "${d}_SYSVERS" for f in "${fs[@]}"; do # les valeurs sont poussés vers la fin si elles existent déjà array_contains ALL_SYSVERS "$f" && array_del ALL_SYSVERS "$f" array_add ALL_SYSVERS "$f" done done } __setup_ALL_SYSvars unset -f __setup_ALL_SYSvars function __compute_local_sysinfos_data() { SYSINFOS_DATA=( "$UNAME_SYSTEM" "$UNAME_MACHINE" "$([ -f /etc/debian_version ] && cat /etc/debian_version)" "$([ -f /etc/gentoo-release ] && cat /etc/gentoo-release)" "$([ -f /etc/oracle-release ] && cat /etc/oracle-release)" "$([ -f /etc/redhat-release ] && cat /etc/redhat-release)" "$([ -f /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist ] && cat /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist)" "$([ -f /System/Library/Frameworks/CoreServices.framework/Resources/version.plist ] && cat /System/Library/Frameworks/CoreServices.framework/Resources/version.plist)" ) } function __dump_remote_sysinfos_data() { "${2:-ssh}" "$1" "\ uname -s echo .----------------. uname -m echo .----------------. [ -f /etc/debian_version ] && cat /etc/debian_version echo .----------------. [ -f /etc/gentoo-release ] && cat /etc/gentoo-release echo .----------------. [ -f /etc/oracle-release ] && cat /etc/oracle-release echo .----------------. [ -f /etc/redhat-release ] && cat /etc/redhat-release echo .----------------. [ -f /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist ] && cat /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/version.plist echo .----------------. [ -f /System/Library/Frameworks/CoreServices.framework/Resources/version.plist ] && cat /System/Library/Frameworks/CoreServices.framework/Resources/version.plist echo .----------------." } function __build_sysinfos_data() { awk ' BEGIN { data = "" have_data = 0 print "SYSINFOS_DATA=(" } function read_data() { if (have_data) data = data "\n" else have_data = 1 data = data $0 } function dump_data() { gsub(/'\''/, "'\'\\\\\'\''", data) print "'\''" data "'\''" data = "" have_data = 0 } $0 == ".----------------." { dump_data(); next } { read_data() } END { dump_data() print ")" } ' } function __compute_sysinfos() { # SYSINFOS_DATA doit être initialisé local system="${SYSINFOS_DATA[0]}" local machine="${SYSINFOS_DATA[1]}" local debian_version="${SYSINFOS_DATA[2]}" local gentoo_release="${SYSINFOS_DATA[3]}" local oracle_release="${SYSINFOS_DATA[4]}" local redhat_release="${SYSINFOS_DATA[5]}" local macosx_plist1="${SYSINFOS_DATA[6]}" local macosx_plist2="${SYSINFOS_DATA[7]}" MYSYSNAME=(unknown) MYSYSDIST=(unknown) MYSYSVER=(unknown) if [ "$system" == "Linux" ]; then case "$machine" in x86_64) MYSYSNAME=(linux64 linux); MYBITS=64;; i386|i586|i686) MYSYSNAME=(linux32 linux); MYBITS=32;; ppc) MYSYSNAME=(linuxppc32 linuxppc linux); MYBITS=32;; ppc64) MYSYSNAME=(linuxppc64 linuxppc linux); MYBITS=64;; arm*) MYSYSNAME=(linuxarm linux);; *) MYSYSNAME=(linux);; esac if [ -n "$debian_version" ]; then case "$debian_version" in 9*|stretch*) MYSYSDIST=(debian debianlike); MYSYSVER=(stretch);; 8*|jessie*) MYSYSDIST=(debian debianlike); MYSYSVER=(jessie);; 7*|wheezy*) MYSYSDIST=(debian debianlike); MYSYSVER=(wheezy);; 6*|squeeze*) MYSYSDIST=(debian debianlike); MYSYSVER=(squeeze);; 5*) MYSYSDIST=(debian debianlike); MYSYSVER=(lenny);; 4*) MYSYSDIST=(debian debianlike); MYSYSVER=(etch);; *) MYSYSDIST=(debianlike);; esac elif [ -n "$gentoo_release" ]; then MYSYSDIST=(gentoo) elif [ -n "$oracle_release" ]; then MYSYSDIST=(ol rhel redhatlike) case "$oracle_release" in Oracle*Linux*release\ 7*) MYSYSVER=(ol7 rhel7 redhat7);; Oracle*Linux*release\ 6*) MYSYSVER=(ol6 rhel6 redhat6);; esac elif [ -n "$redhat_release" ]; then case "$redhat_release" in Fedora*) MYSYSDIST=(fedora redhatlike);; Red*Hat*Enterprise*Linux*) MYSYSDIST=(rhel redhatlike);; CentOS*) MYSYSDIST=(centos redhatlike);; *) MYSYSDIST=(redhatlike);; esac case "$redhat_release" in Fedora*14*) MYSYSVER=(fedora14);; Fedora*13*) MYSYSVER=(fedora13);; Fedora*12*) MYSYSVER=(fedora12);; Fedora*11*) MYSYSVER=(fedora11);; Red*Hat*Enterprise*Linux*release\ 7*) MYSYSVER=(rhel7 redhat7);; Red*Hat*Enterprise*Linux*release\ 6*) MYSYSVER=(rhel6 redhat6);; Red*Hat*Enterprise*Linux*release\ 5*) MYSYSVER=(rhel5 redhat5);; Red*Hat*Enterprise*Linux*release\ 4*) MYSYSVER=(rhel4 redhat4);; CentOS*release\ 7*) MYSYSVER=(centos7 redhat7);; CentOS*release\ 6*) MYSYSVER=(centos6 redhat6);; CentOS*release\ 5*) MYSYSVER=(centos5 redhat5);; CentOS*release\ 4*) MYSYSVER=(centos4 redhat4);; esac fi elif [ "$system" == "Darwin" ]; then function get_macosx_version() { local plist for plist in "$@"; do [ -n "$plist" ] || continue echo "$plist" | grep -A 1 CFBundleShortVersionString | grep string | sed 's/.*//g s/<\/string>.*$//g' break done } MYSYSNAME=(macosx darwin) case "$(get_macosx_version "$macosx_plist1" "$macosx_plist2")" in 10.7*) MYSYSDIST=(lion);; 10.6*) MYSYSDIST=(snowleopard);; 10.5*) MYSYSDIST=(leopard);; 10.4*) MYSYSDIST=(tiger);; 10.3*) MYSYSDIST=(panther);; esac MYSYSVER=() fi } function compute_local_sysinfos() { local SYSINFOS_DATA __compute_local_sysinfos_data __compute_sysinfos if [ -n "$UTOOLS_CHROOT" ]; then # Dans un chroot, il est possible de forcer les valeurs [ -n "$UTOOLS_SYSNAME" ] && eval "MYSYSNAME=($UTOOLS_SYSNAME)" [ -n "$UTOOLS_BITS" ] && eval "MYBITS=$UTOOLS_BITS" [ -n "$UTOOLS_SYSDIST" ] && eval "MYSYSDIST=($UTOOLS_SYSDIST)" [ -n "$UTOOLS_SYSVER" ] && eval "MYSYSVER=($UTOOLS_SYSVER)" fi } function compute_remote_sysinfos() { local SYSINFOS_DATA eval "$(__dump_remote_sysinfos_data "$@" | __build_sysinfos_data)" __compute_sysinfos } SYSINFOSLOCALS="\ local -a MYSYSNAME MYSYSDIST MYSYSVER local MYBITS" MYSYSNAME=() MYBITS= MYSYSDIST=() MYSYSVER=() compute_local_sysinfos function __get_sysdist_alias() { if ! array_contains ALL_SYSDISTS "$1"; then local nd n d for nd in "${SYSDIST_ALIASES[@]}"; do splitvar "$nd" n d if [ "$n" == "$1" ]; then echo "$d" return fi done fi echo "$1" } function __get_sysver_alias() { if ! array_contains ALL_SYSVERS "$1"; then local nv n v for nv in "${SYSVER_ALIASES[@]}"; do splitvar "$nv" n v if [ "$n" == "$1" ]; then echo "$v" return fi done fi echo "$1" } function __fix_sysinfos_upward() { local sysname_ sysdists_ sysdist_ sysvers_ sysver_ if [ -z "${!sysnamevar_}" ]; then if [ -z "${!sysdistvar_}" ]; then [ -z "${!sysvervar_}" ] && return # essayer de déterminer !sysdistvar_ à partir de !sysvervar_ for sysname_ in "${SYSNAMES[@]}"; do array_copy sysdists_ "${sysname_}_SYSDISTS" for sysdist_ in "${sysdists_[@]}"; do array_copy sysvers_ "${sysdist_}_SYSVERS" for sysver_ in "${sysvers_[@]}"; do if [ "$sysver_" == "${!sysvervar_}" ]; then set_var "$sysdistvar_" "$sysdist_" set_var "$sysnamevar_" "$sysname_" return fi done done done fi [ -z "${!sysdistvar_}" ] && return 0 # essayer de déterminer !sysnamevar_ à partir de !sysdistvar_ for sysname_ in "${SYSNAMES[@]}"; do array_copy sysdists_ "${sysname_}_SYSDISTS" for sysdist_ in "${sysdists_[@]}"; do if [ "$sysdist_" == "${!sysdistvar_}" ]; then set_var "$sysnamevar_" "$sysname_" return fi done done fi } function __fix_sysinfos_downward() { local sysname_ sysdist_ sysver_ # si !sysnamevar_ n'est pas défini, on ne peut rien faire [ -z "${!sysnamevar_}" ] && return if [ -z "${!sysdistvar_}" ]; then # essayer de déterminer !sysdistvar_ à partir de !sysnamevar_ array_copy sysdists_ "${!sysnamevar_}_SYSDISTS" for sysdist_ in "${sysdists_[@]}"; do set_var "$sysdistvar_" "$sysdist_" break done fi [ -z "${!sysdistvar_}" ] && return if [ -z "${!sysvervar_}" ]; then # essayer de déterminer !sysvervar_ à partir de !sysdistvar_ array_copy sysvers_ "${sysdistvar_}_SYSVERS" for sysver_ in "${sysvers_[@]}"; do set_var "$sysvervar_" "$sysver_" break done fi #[ -z "${!sysvervar_}" ] && return } function ensure_sysinfos() { # Essayer de déterminer les valeurs des variables $1(=SYSNAME), $2(=SYSDIST) # et $3(=SYSVER) en fonction des valeurs des autres. Cette fonction est à # utiliser quand on récupère cette information de la part de l'utilisateur, # et qu'il faut compléter local sysnamevar_="${1:-SYSNAME}" local sysdistvar_="${2:-SYSDIST}" local sysvervar_="${3:-SYSVER}" [ -n "${!sysdistvar_}" ] && set_var "$sysdistvar_" "$(__get_sysdist_alias "${!sysdistvar_}")" [ -n "${!sysvervar_}" ] && set_var "$sysvervar_" "$(__get_sysver_alias "${!sysvervar_}")" __fix_sysinfos_upward __fix_sysinfos_downward } function dump_sysinfos_desc() { # Afficher les valeurs de SYSNAME, SYSDIST, SYSVER qui décrivent le système # actuel local sysname_="${1:-MYSYSNAME}[*]" local sysdist_="${2:-MYSYSDIST}[*]" local sysver_="${3:-MYSYSVER}[*]" echo "\ sysname: ${!sysname_} sysdist: ${!sysdist_} sysver: ${!sysver_}" } function get_sysinfos_desc() { # Afficher une chaine de la forme SYSNAME/SYSDIST/SYSVER qui décrit le # système actuel local sysname_="${1:-MYSYSNAME}"; sysname_="${!sysname_}" local sysdist_="${2:-MYSYSDIST}"; sysdist_="${!sysdist_}" local sysver_="${3:-MYSYSVER}"; sysver_="${!sysver_}" echo "$sysname_${sysdist_:+/$sysdist_}${sysver_:+/$sysver_}" } function check_sysinfos() { # Tester si le système courant ($MYSYSNAME, $MYSYSDIST, $MYSYSVER, $MYBITS) # correspond à au moins un des arguments. # Il est possible de spécifier des variables différentes pour tester le # système courant avec l'option --vars qui doit être spécifiée en premier: # check_sysinfos --vars sysname sysdist sysver bits -d debian # Les options -s, -d, -v, -b permettent respectivement de vérifier le # système, la distribution, la version et le nombre de bits. Il est possible # de spécifier plusieurs tests à effectuer, e.g.: # check_sysinfos -d debian ubuntu -b 64 # pour tester si l'on est sur une distribution debian ou ubuntu *et* sur un # système 64 bits # Note: avec l'option --vars, il peut arriver que sysname, sysdist ou sysver # ne soient pas des tableaux mais des variables scalaires, surtout si elles # sont fournies par l'utilisateur. Il est conseillé dans ce cas de tester # toutes les possibilités quand on vérifie une valeur, e.g.: # check_sysinfos --vars sysname sysdist sysver bits -s linux64 linux32 linux # pour tester si on est sur un système linux # Avec l'option -v, il est possible de suffixer la valeur avec + ou - selon # que l'on veut toutes les versions situées après ou avant la version # spécifiée. Attention, à cause d'une limitation de l'implémentation, il # faut alors impérativement filtrer aussi sur la distribution, e.g: # check_sysinfo -d debian -v lenny+ # pour tester si on est en lenny ou en squeeze. # De même, l'option -d accepte aussi de suffixer la valeur avec + ou -, mais # cela n'a actuellement de sens qu'avec les version de MacOS X. Il faut # aussi impérativement filtrer sur le système, e.g: # check_sysinfos -s macosx -d 10.5+ local sysnamevar_ sysdistvar_ sysvervar_ bitsvar_ if [ "$1" == --vars ]; then shift if [[ "$1" != -* ]]; then sysnamevar_="${1:-MYSYSNAME}"; shift; fi if [[ "$1" != -* ]]; then sysdistvar_="${1:-MYSYSDIST}"; shift; fi if [[ "$1" != -* ]]; then sysvervar_="${1:-MYSYSVER}"; shift; fi if [[ "$1" != -* ]]; then bitsvar_="${1:-MYBITS}"; shift; fi else sysnamevar_="MYSYSNAME" sysdistvar_="MYSYSDIST" sysvervar_="MYSYSVER" bitsvar_="MYBITS" fi local check_=sysname r_=0 while [ -n "$1" ]; do if [[ "$1" == -* ]]; then [ "$1" == "-S" ] && { sysnamevar_="$2"; shift 2; continue; } [ "$1" == "-D" ] && { sysdistvar_="$2"; shift 2; continue; } [ "$1" == "-V" ] && { sysvervar_="$2"; shift 2; continue; } [ "$1" == "-B" ] && { bitsvar_="$2"; shift 2; continue; } [ "$r_" == "1" ] && break [ "$1" == "-s" ] && check_=sysname [ "$1" == "-d" ] && check_=sysdist [ "$1" == "-v" ] && check_=sysver [ "$1" == "-b" ] && check_=bits r_=1 shift continue fi if [ "$check_" == "sysname" ]; then if array_contains "$sysnamevar_" "$1"; then r_=0 check_=skip fi elif [ "$check_" == "sysdist" ]; then local mode_=exact value_="$1" if [ "${value_%+}" != "$value_" ]; then mode_=after value_="${value_%+}" elif [ "${value_%-}" != "$value_" ]; then mode_=before value_="${value_%-}" fi value_="$(__get_sysdist_alias "$value_")" if [ "$mode_" == "exact" ]; then if array_contains "$sysdistvar_" "$value_"; then r_=0 check_=skip fi elif [ "$mode_" == "after" ]; then local sysdist_ for sysdist_ in "${ALL_SYSDISTS[@]}"; do if array_contains "$sysdistvar_" "$sysdist_"; then r_=0 check_=skip [ "$sysdist_" == "$value_" ] && break elif [ "$sysdist_" == "$value_" ]; then break fi done elif [ "$mode_" == "before" ]; then local sysdist_ found_ for sysdist_ in "${ALL_SYSDISTS[@]}"; do [ "$sysdist_" == "$value_" ] && found_=1 if [ -n "$found_" ]; then if array_contains "$sysdistvar_" "$sysdist_"; then r_=0 check_=skip break fi fi done fi elif [ "$check_" == "sysver" ]; then local mode_=exact value_="$1" if [ "${value_%+}" != "$value_" ]; then mode_=after value_="${value_%+}" elif [ "${value_%-}" != "$value_" ]; then mode_=before value_="${value_%-}" fi value_="$(__get_sysver_alias "$value_")" if [ "$mode_" == "exact" ]; then if array_contains "$sysvervar_" "$value_"; then r_=0 check_=skip fi elif [ "$mode_" == "after" ]; then local sysver_ for sysver_ in "${ALL_SYSVERS[@]}"; do if array_contains "$sysvervar_" "$sysver_"; then r_=0 check_=skip [ "$sysver_" == "$value_" ] && break elif [ "$sysver_" == "$value_" ]; then break fi done elif [ "$mode_" == "before" ]; then local sysver_ found_ for sysver_ in "${ALL_SYSVERS[@]}"; do [ "$sysver_" == "$value_" ] && found_=1 if [ -n "$found_" ]; then if array_contains "$sysvervar_" "$sysver_"; then r_=0 check_=skip break fi fi done fi elif [ "$check_" == "bits" ]; then if [ "$1" == "${!bitsvar_}" ]; then r_=0 check_=skip fi fi shift done return $r_ } # fonctions de support pour tester certaines versions de debian # utilisation: # on_debian # if on_jessie; then xxx # elif on_wheezy; then yyy # elif on_squeeze; then zzz # else ttt # fi # OU: # on_debian: # on_jessie xxx # on_wheezy yyy # on_squeeze zzz # on_default ttt # Sans arguments, on_{jessie,wheezy,squeeze} testent si on est sur la version # demandée OU SUPERIEURE. Avec un argument, la version EXACTE est testée, et la # commande est lancée en cas de correspondance # la forme 'on_debian CMD' est supporté aussi et permet de lancer CMD si on est # sur debian, e.g.: # on_debian pkg_check_install dot graphviz # on_default ewarn "Il faut installer graphviz manuellement" function on_debian() { # Tester si on est sur debian. charger le module debian si c'est le cas. # Si une commande $1..@ est spécifiée, la lancer, mais il n'est alors plus # possible de lancer des tests plus spécifiques avec __on_debian() NUTOOLS_ON_DEBIAN= if check_sysinfos -d debian; then urequire debian if [ $# -gt 0 ]; then NUTOOLS_ON_DEBIAN=debian "$@" else NUTOOLS_ON_DEBIAN=1 fi return 0 else return 1 fi } function on_debian:() { on_debian "$@"; } function __on_debian() { [ -z "$NUTOOLS_ON_DEBIAN" -o "$NUTOOLS_ON_DEBIAN" != 1 ] && return 1 local sysver="$1"; shift if [ $# -gt 0 ]; then if check_sysinfos -d debian -v "$sysver"; then NUTOOLS_ON_DEBIAN="$sysver" "$@" return 0 else return 1 fi else if check_sysinfos -d debian -v "$sysver+"; then NUTOOLS_ON_DEBIAN="$sysver" return 0 fi fi } function on_stretch() { __on_debian stretch "$@"; } function on_jessie() { __on_debian jessie "$@"; } function on_wheezy() { __on_debian wheezy "$@"; } function on_squeeze() { __on_debian squeeze "$@"; } function on_default() { if [ "$NUTOOLS_ON_DEBIAN" == 1 ]; then if [ $# -gt 0 ]; then "$@" return 0 else return 0 fi elif [ -n "$NUTOOLS_ON_DEBIAN" ]; then return 1 fi #XXX ici, on peut ajouter le code de support pour d'autres systèmes return 1 }