From 48a841fc6fabef5752e8f37dd52a24c168230173 Mon Sep 17 00:00:00 2001 From: Jephte CLAIN Date: Mon, 27 Jan 2014 17:13:57 +0400 Subject: [PATCH] =?UTF-8?q?suite=20d=C3=A9veloppement=20network=5Fconfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ulib/debian | 428 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 347 insertions(+), 81 deletions(-) diff --git a/ulib/debian b/ulib/debian index 3523967..b393db1 100644 --- a/ulib/debian +++ b/ulib/debian @@ -112,12 +112,43 @@ END { }' } +__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS= + function __network_hostname() { - echo "${1%%.*}" >/etc/hostname + local hostname="${1%%.*}" + if [ -n "$__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS" ]; then + uecho "Setting /etc/hostname to $hostname" + else + echo "$hostname" >/etc/hostname + fi } function __network_mailname() { - echo "$1" >/etc/mailname + local host="$1" + if [ -n "$__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS" ]; then + uecho "Setting /etc/mailname to $host" + else + echo "$host" >/etc/mailname + fi +} + +function __network_fix_exim4() { + local host="$1" + local tmpfile; ac_set_tmpfile tmpfile + + "$tmpfile" + if [ -n "$__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS" ]; then + if testdiff "$tmpfile" /etc/exim4/update-exim4.conf.conf; then + uecho "Setting /etc/exim4/update-exim4.conf.conf to:" + cat "$tmpfile" | sed 's/^/ /g' 1>&2 + else + uecho "/etc/exim4/update-exim4.conf.conf: pas de modifications" + fi + elif testdiff "$tmpfile" /etc/exim4/update-exim4.conf.conf; then + cat "$tmpfile" >/etc/exim4/update-exim4.conf.conf + update-exim4.conf + fi } function __network_hosts() { @@ -127,92 +158,331 @@ function __network_hosts() { /^127\\.[0-9]\\+\\.[0-9]\\+\\.[0-9]\\+[ $TAB]*\$/d" >"$tmpfile" local sip="${ip//./\\.}" shost="${host//./\\.}" if ! quietgrep "^$sip[ $TAB]\\+$shost[ $TAB]\\+$hostname" "$tmpfile"; then - sed -i "/^$sip/d; 1i\\ + sed -i "/^$sip[ $TAB]/d" "$tmpfile" + sed -i "1i\\ $ip$TAB$host $hostname" "$tmpfile" fi - testdiff "$tmpfile" /etc/host && cat "$tmpfile" >/etc/hosts + if [ -n "$__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS" ]; then + if testdiff "$tmpfile" /etc/hosts; then + uecho "Setting /etc/hosts to:" + cat "$tmpfile" | sed 's/^/ /g' 1>&2 + else + uecho "/etc/hosts: pas de modifications" + fi + elif testdiff "$tmpfile" /etc/hosts; then + cat "$tmpfile" >/etc/hosts + fi ac_clean "$tmpfile" } -function __network_fix_mainip() { - splitfsep2 "$1" : "${2:-mainiface}" "${3:-mainip}" +function __network_parse_confip() { + # confip --> iface [ipspecs@] [ipspecs] + local __npc_tmp + splitfsep2 "$1" : "${2:-iface}" __npc_tmp + [ -n "$3" ] && array_split "$3" "$__npc_tmp" , + [ -n "$4" ] && set_var "$4" "$__npc_tmp" } -function __network_fix_supplips() { - local -a __sips __ifaces __ips - local __sip __iface __sip_ips - array_copy __sips "$1" - # recenser les interfaces et créer les tableaux - for __sip in "${__sips[@]}"; do - splitfsep2 "$__sip" : __iface __sip_ips - array_addu __ifaces "$__iface" - eval "local -a __${__iface}_iface_ips" +function __network_parse_ipspec() { + # ipspec --> ip mask gateway + local __npi_tmp + splitfsep "$1" / "${2:-ip}" __npi_tmp + splitfsep "$__npi_tmp" + "${3:-mask}" "${4:-gateway}" +} + +function __network_parse_confbr() { + # confbr --> br [ifaces@] [ifaces] + local __npc_tmp + splitfsep "$1" : "${2:-br}" __npc_tmp + [ -n "$3" ] && array_split "$3" "$__npc_tmp" , + [ -n "$4" ] && set_var "$4" "$__npc_tmp" +} + +function __network_fix_confips() { + # confips@ + local -a __nfc_confips __nfc_ipspecs __nfc_ifaces __nfc_ips + local __nfc_confip __nfc_iface __nfc_ipspec __nfc_ip __nfc_mask __nfc_gateway + + array_copy __nfc_confips "${1:-confips}" + # recenser les interfaces et créer les tableaux __IFACE_ipspecs + for __nfc_confip in "${__nfc_confips[@]}"; do + __network_parse_confip "$__nfc_confip" __nfc_iface __nfc_ipspecs + array_addu __nfc_ifaces "$__nfc_iface" + eval "local -a __nfc_${__nfc_iface}_ipspecs" done # puis constuire la liste des adresses IP associées à chaque interface - for __sip in "${__sips[@]}"; do - splitfsep2 "$__sip" : __iface __sip_ips - array_split __ips "$__sip_ips" , - eval "array_extendu __${__iface}_iface_ips __ips" + for __nfc_confip in "${__nfc_confips[@]}"; do + __network_parse_confip "$__nfc_confip" __nfc_iface __nfc_ipspecs + for __nfc_ipspec in "${__nfc_ipspecs[@]}"; do + __network_parse_ipspec "$__nfc_ipspec" __nfc_ip __nfc_mask __nfc_gateway + if ! array_contains __nfc_ips "$__nfc_ip"; then + eval "array_add __nfc_${__nfc_iface}_ipspecs \"$__nfc_ipspec\"" + array_add __nfc_ips "$__nfc_ip" + fi + done done # puis construire le tableau final - array_new __sips - for __iface in "${__ifaces[@]}"; do - array_add __sips "${__iface:-eth0}:$(array_join "__${__iface}_iface_ips" ,)" + array_new __nfc_confips + for __nfc_iface in "${__nfc_ifaces[@]}"; do + array_add __nfc_confips "$__nfc_iface:$(array_join "__nfc_${__nfc_iface}_ipspecs" ,)" done - array_copy "$1" __sips + + array_copy "${1:-confips}" __nfc_confips } function __network_fix_confbrs() { - local -a __confbrs __brs __ifaces - local __confbr __br __confbr_ifaces - array_copy __confbrs "$1" - # recenser les bridges et créer les tableaux - for __confbr in "${__confbrs[@]}"; do - splitfsep2 "$__confbr" : __br __confbr_ifaces - array_addu __brs "$__br" - eval "local -a ${__br}_br_ifaces" + # confbrs@ + local -a __nfc_confbrs __nfc_ifaces __nfc_brs __nfc_ips + local __nfc_confbr __nfc_br __nfc_iface __nfc_ip __nfc_mask __nfc_gateway + + array_copy __nfc_confbrs "${1:-confbrs}" + # recenser les bridges et créer les tableaux __BR_ifaces + for __nfc_confbr in "${__nfc_confbrs[@]}"; do + __network_parse_confbr "$__nfc_confbr" __nfc_br __nfc_ifaces + array_addu __nfc_brs "$__nfc_br" + eval "local -a __nfc_${__nfc_br}_ifaces" done # puis constuire la liste des interfaces associées à chaque bridge - for __confbr in "${__confbrs[@]}"; do - splitfsep2 "$__confbr" : __br __confbr_ifaces - array_split __ifaces "$__confbr_ifaces" , - eval "array_extendu ${__br}_br_ifaces __ifaces" + for __nfc_confbr in "${__nfc_confbrs[@]}"; do + __network_parse_confbr "$__nfc_confbr" __nfc_br __nfc_ifaces + array_extendu "__nfc_${__nfc_br}_ifaces" __nfc_ifaces done # puis construire le tableau final - array_new __confbrs - for __br in "${__brs[@]}"; do - array_add __confbrs "${__br:-br0}:$(array_join "${__br}_br_ifaces" ,)" + array_new __nfc_confbrs + for __nfc_br in "${__nfc_brs[@]}"; do + array_add __nfc_confbrs "$__nfc_br:$(array_join "__nfc_${__nfc_br}_ifaces" ,)" done - array_copy "$1" __confbrs + + array_copy "${1:-confbrs}" __nfc_confbrs +} + +function __network_resolve_mainiface() { + local __nrm_mainiface="${1:-mainiface}" __nrm_mainconfbr="$2" __nrm_mainconfip="$3" + [ -n "${!__nrm_mainiface}" ] || __network_parse_confbr "$__nrm_mainconfbr" "$__nrm_mainiface" + [ -n "${!__nrm_mainiface}" ] || __network_parse_confip "$__nrm_mainconfip" "$__nrm_mainiface" + [ -n "${!__nrm_mainiface}" ] || set_var "$__nrm_mainiface" eth0 +} + +function __network_set_mainip() { + eval "$(ip addr show dev "$1" | awk "BEGIN { + mainipvar = \"${2:-mainip}\" + netmaskvar = \"${3:-netmask}\" + broadcastvar = \"${4:-broadcast}\" +"' + print mainipvar "=" + print netmaskvar "=" + print broadcastvar "=" +} +$1 == "inet" { + mainip = ""; netmask = ""; broadcast = "" + if (match($0, "inet ([^ ]*)/([^ ]*) ", vs) != 0) { + mainip = vs[1] + netmask = vs[2] + } + if (match($0, "brd ([^ ]*) ", vs) != 0) { + broadcast = vs[1] + } + print mainipvar "=\"" mainip "\"" + print netmaskvar "=\"" netmask "\"" + print broadcastvar "=\"" broadcast "\"" + exit 0 +}')" +} + +function __network_set_gateway() { + eval "$(route -n | awk "BEGIN { + iface = \"$1\" + gatewayvar = \"${2:-gateway}\" +"' + print gatewayvar "=" +} +$1 == "0.0.0.0" && $8 == iface { + print gatewayvar "=\"" $2 "\"" +}')" +} + + + #XXX + #local mainnetmask mainbroadcast maingateway + #if [ "$mainip" == dhcp ]; then + # # ne pas toucher aux adresses en dhcp + # : + #elif [ -z "$mainip" ]; then + # # détecter les valeurs par rapport à l'environnement + # __network_set_mainip "$mainiface" mainip mainnetmask mainbroadcast + # __network_set_gateway "$mainiface" maingateway + #fi + # quelques pistes de réflexion pour la suite de l'implémentation: + + # après avoir classifiée les bridge et les interfaces non attachées à des + # bridges, il faut: configurer les interfaces standard, configurer les + # interfaces des bridges en manual, configurer les bridges + # si l'interface principale est un bridge, il faut mettre les interfaces + # concernées en manual et configurer les adresses ips du bridge + # si l'interface principale est une interface standard, il suffit de + # configurer les adresses pour cette interface. + + +function __network_update_bridge() { + # vérifier la configuration (interfaces de ifaces[@] en manual, présence du + # bridge, bridge en auto, adresse ip principale statique ou en dhcp, + # adresses ip supplémentaires), puis si nécessaire, supprimer l'ancienne + # configuration et créer la nouvelle. + awkrun -f iface="$1" ipspecs="${2:-ipspecs}[@]" ifaces="${3:-ifaces}[@]" ' +{ print } +' +} + +function __network_update_iface() { + # vérifier la configuration (présence de l'interface, interface en auto, + # adresse ip principale statique ou en dhcp, adresses ip supplémentaires), + # puis si nécessaire, supprimer l'ancienne configuration et créer la + # nouvelle. + awkrun -f iface="$1" ipspecs[@] ' +{ print } +' } function network_config() { # (Re)configurer le réseau sur l'hôte courant. - # $1 (host) est le nom d'hôte, $2 (mainip) l'adresse ip principale, $3 - # (netmask) le masque de sous-réseau, $4 (broadcast) l'adresse de broadcast, - # $5 (gateway) la passerelle, $6 (supplips) le nom d'un tableau contenant - # des adresses ip supplémentaires, et $7 (brs) le nom d'un tableau contenant - # les bridges à configurer. + # $1 (host) est le nom d'hôte. $2 (confips) est le nom d'un tableau + # contenant la configuration des adresses ips pour les interfaces. $3 + # (confbrs) est le nom d'un tableau contenant la configuration des bridges à + # créer/mettre à jour. $4 (mainiface) est le nom de l'interface + # principale. En principe, l'interface principale est le premier bridge + # défini ou la première interface définie. # Si un des arguments n'est pas spécifié, il est ignoré. - # netmask, broadcast et gateway sont ignorés si ip n'est pas spécifié. - # mainip est de la forme [iface:]address. iface vaut par défaut eth0 - # Le tableau supplips doit contenir des définitions de la forme - # [iface:]addresses. iface vaut par défaut eth0. addresses est une liste - # d'adresses ip séparées par une virgule. e.g. br0:10.82.80.65,10.82.80.66 - # Le tableau brs doit contenir des définitions de la forme br:ifaces. br est - # le nom du bridge, e.g. br0. ifaces est une liste d'interfaces séparées par - # une virgule. e.g. br0:eth0,eth1 + # Le tableau confips doit contenir des définitions d'une des formes + # suivantes: + # [iface:]address[/mask][+gateway],... + # [iface:]dhcp + # La deuxième forme est pour spécifier qu'une interface est configurée par + # DHCP. iface vaut par défaut eth0, sauf si une définition de bridge + # existe, auquel cas il s'agit du premier bridge défini. Pour chaque + # interface, seule la première spécification d'adresse IP tient compte de + # l'argument gateway. Les autres spécifications définissent des adresses IP + # supplémentaires pour l'interface. + # Le tableau brs doit contenir des définitions de la forme suivante: + # br:ifaces,... + # br est le nom du bridge, e.g. br0. ifaces est une liste d'interfaces + # séparées par une virgule. e.g. br0:eth0,eth1 + # Bien que ce soit techniquement possible, ce script interdit que l'on + # définisse une adresse IP pour une interface faisant partie d'un bridge. urequire ipcalc conf - local -a __nc_supplips __nc_brs - [ -n "$6" ] && array_copy __nc_supplips "$7" - [ -n "$7" ] && array_copy __nc_brs "$8" + local -a __nc_confips __nc_confbrs + [ -n "$2" ] && array_copy __nc_confips "$2" + [ -n "$3" ] && array_copy __nc_confbrs "$3" - local host="$1" mainip="$2" netmask="${3:-255.255.255.0}" broadcast="$4" gateway="$5" mainiface="$6" - local -a supplips brs - array_copy supplips __nc_supplips - array_copy brs __nc_brs + local host="$1" mainiface="$4" + local -a confips confbrs + array_copy confips __nc_confips + array_copy confbrs __nc_confbrs + + __network_fix_confips confips + __network_fix_confbrs confbrs + + local mainbr # bridge principal + local mainip # adresse IP principale de l'interface principale + local confbr confip br iface mask gateway + local -a ipspecs + + __network_resolve_mainiface mainiface "${confbrs[0]}" "${confips[0]}" + __network_parse_confbr "${confbrs[0]}" mainbr + [ -n "$mainbr" ] || mainbr=br0 + + if [ -n "${confips[*]}" -o -n "${confbrs[*]}" ]; then + # Vérifier qu'une interface avec une adresse IP ne figure pas dans les + # bridges à configurer. en profiter pour classer les interfaces par + # type: standard et bridges + etitle "Configuration des interfaces réseau" + + local -a ifaces_with_ips ifaces + local -a brifaces + ifaces_with_ips=() + for confip in "${confips[@]}"; do + __network_parse_confip "$confip" iface + array_addu ifaces_with_ips "$iface" + done + for confbr in "${confbrs[@]}"; do + __network_parse_confbr "$confbr" br ifaces + array_add brifaces "$br" + for iface in "${ifaces[@]}"; do + if array_contains ifaces_with_ips "$iface"; then + eerror "$iface: Impossible de configurer une interface dans un bridge ET avec une adresse IP" + return 1 + fi + done + done + local -a confstdips confbrips + for confip in "${confips[@]}"; do + __network_parse_confip "$confip" iface + if array_contains brifaces "$iface"; then + array_add confbrips "$confip" + else + array_add confstdips "$confip" + fi + done + + # maintenant, configurer /etc/network/interfaces: faire une copie de travail + local interfaces workfile + ac_set_tmpfile interfaces + ac_set_tmpfile workfile + cat /etc/network/interfaces >"$interfaces" + + # configurer chaque bridge + local -a tmpifaces + local tmpbr + for confip in "${confbrips[@]}"; do + __network_parse_confip "$confip" br ipspecs + [ -n "$br" ] || br="$mainbr" + + if [ -z "$mainip" -a "$br" == "$mainiface" ]; then + __network_parse_ipspec "${ipspecs[0]}" mainip mask gateway + fi + + ifaces=() + for confbr in "${confbrs[@]}"; do + __network_parse_confbr "$confbr" tmpbr tmpifaces + if [ "$tmpbr" == "$br" ]; then + array_copy ifaces "$tmpifaces" + break + fi + done + + __network_update_bridge "$br" ipspecs ifaces <"$interfaces" >"$workfile" + cat "$workfile" >"$interfaces" + done + + # configurer chaque interface classique + for confip in "${confstdips[@]}"; do + __network_parse_confip "$confip" iface ipspecs + [ -n "$iface" ] || iface="$mainiface" + + if [ -z "$mainip" -a "$iface" == "$mainiface" ]; then + __network_parse_ipspec "${ipspecs[0]}" mainip mask gateway + fi + + __network_update_iface "$iface" ipspecs <"$interfaces" >"$workfile" + cat "$workfile" >"$interfaces" + done + + # Fin de traitement + if [ -n "$__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS" ]; then + if testdiff "$interfaces" /etc/network/interfaces; then + uecho "Setting /etc/network/interfaces to:" + cat "$interfaces" | sed 's/^/ /g' 1>&2 + else + uecho "/etc/network/interfaces: pas de modifications" + fi + elif testdiff "$interfaces" /etc/network/interfaces; then + cat "$interfaces" >/etc/network/interfaces + fi + ac_clean "$interfaces" "$workfile" + + eend + fi # configurer le nom d'hôte if [ -n "$host" ]; then @@ -221,40 +491,36 @@ function network_config() { # si on ne spécifie pas l'adresse ip principale, la résoudre ici. ceci # est nécessaire pour mettre à jour /etc/hosts - local ip="$mainip" - if [ -z "$ip" ]; then - local -a ips - resolv_ips ips "$host" - [ -n "${ips[*]}" ] || { + if [ "$mainip" == dhcp ]; then + # si l'adresse obtenue est en DHCP, ne pas mettre à jour /etc/hosts + mainip= + elif [ -z "$mainip" ]; then + local -a mainips + resolv_ips mainips "$host" + [ -n "${mainips[*]}" ] || { eerror "$host: Impossible de résoudre ce nom d'hôte" return 1 } - ip="${ips[0]}" + mainip="${mainips[0]}" fi estep "/etc/hostname" __network_hostname "$host" estep "/etc/mailname" __network_mailname "$host" - estep "/etc/hosts" - __network_hosts "$host" "$ip" + if [ -f "/etc/exim4/update-exim4.conf.conf" ]; then + estep "/etc/exim4/update-exim4.conf.conf" + __network_fix_exim4 "$host" + fi + # XXX tester la présence éventuelle de postfix, et si nécessaire, + # modifier la configuration + if [ -n "$mainip" ]; then + estep "/etc/hosts" + __network_hosts "$host" "$mainip" + fi eend fi - # quelques pistes de réflexion pour la suite de l'implémentation: - - # pour la configuration de l'adresse ip principale, il faut d'abord - # déterminer l'interface principale - # si l'interface principale est un bridge, il faut mettre les interfaces - # concernées en manual et configurer les adresses ips du bridge - # si l'interface principale est une interface standard, il suffit de - # configurer les adresses pour cette interface. - # bien que possible en pratique, interdire qu'une interface soit membre d'un - # bridge et aie une adresse. - # après avoir classifiée les bridge et les interfaces non attachées à des - # bridges, il faut: configurer les interfaces standard, configurer les - # interfaces des bridges en manual, configurer les bridges - return 0 }