##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8 ## Outils pour les distributions debian ##@cooked nocomments ##@require base ##@require sysinfos ##@require service uprovide debian urequire base sysinfos service ################################################################################ # Gestion des packages function pkg_check() { # Vérifier que les packages sont installés sur le système local pkg status for pkg in "$@"; do status="$(LANG=C dpkg -s "$pkg" 2>/dev/null | grep '^Status:')" || return 1 [[ "$status" == *not-installed* ]] && return 1 [[ "$status" == *deinstall* ]] && return 1 done return 0 } function pkg_update() { # Mettre à jour la liste des packages silencieusement sans confirmation LANG=C apt-get update -qy } function pkg_upgrade() { # Mettre à jour la liste des packages silencieusement sans confirmation LANG=C apt-get upgrade -qy } function pkg_install() { # Installer les packages silencieusement et sans confirmation LANG=C apt-get install -qy "$@" } function pkg_installm() { # Installer les packages silencieusement et sans confirmation # Retourner 0 si au moins un des packages a été installé. Sinon, les # packages n'ont pas été installés, soit parce qu'ils sont déjà installé, # soit parce qu'il y a eu une erreur. if ! pkg_check "$@"; then # essayer d'installer les packages pkg_install "$@" else # aucun package n'a été installé return 1 fi } ################################################################################ # Gestion des services function service_disable() { # Désactiver le service $1 pour qu'il ne se lance pas automatiquement au # démarrage update-rc.d -f "$1" remove } function service_enable() { # Activer le service $1 pour qu'il se lance automatiquement au démarrage update-rc.d "$1" defaults } ################################################################################ # Gestion des interfaces réseau function network_create_bridge() { # Modifier le fichier /etc/network/interfaces pour créer un nouveau pont # nommé $1 avec les paramètres $2. Si $2 est vide, sa valeur par défaut est # bridge_ports none # bridge_stp off # bridge_fd 2 # bridge_maxwait 0 # OPTIONS: # --static L'interface est statique plutôt que de recevoir son # adresse par DHCP # --auto Démarrer l'interface automatiquement # Une définition existante de l'interface n'est jamais écrasée. # Retourner vrai si la définition a été ajoutée dans /etc/network/interfaces local args method auto ifname lines method=dhcp parse_opts \ --static method=static \ --auto auto \ @ args -- "$@" && set -- "${args[@]}" || { eerror "$args" return 1 } ifname="${1:-br0}" array_from_lines lines "$2" lines="$(array_to_lines lines "" " ")" doinplacef /etc/network/interfaces awkrun ifname="$ifname" lines="$lines" method="$method" auto="$auto" ' BEGIN { foundif = 0 } $0 ~ "^iface " ifname " " { foundif = 1 } { print } END { if (foundif) { exit 1 } else { print "" if (auto != "") print "auto " ifname print "iface " ifname " inet " method if (lines != "") print lines exit 0 } }' } __DEBIAN_NETWORK_DEVEL_SHOW_MODIFS= function debian_network_fix_confbrs() { : } function debian_network_fix_confips() { # $2==mainiface, l'interface associée aux adresses ip non qualifiées : } function debian_network_fix_mainiface() { # confips[0] est la configuration ip de l'interface principale : } function debian_network_fix_confs() { network_fix_confbrs "${1:-confbrs}" network_fix_confips "${2:-confips}" network_fix_mainiface "${1:-confbrs}" "${2:-confips}" "$3" } #XXX function debian_network_backup() { local file="$1" local backup="$file.orig$(date +%Y%m%d)" [ -f "$backup" ] || cat "$file" >"$backup" 2>/dev/null } function debian_network_hostname() { local hostname="${1%%.*}" [ -f /etc/hostname ] || touch /etc/hostname if [ -n "$__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS" ]; then uecho "Setting /etc/hostname to $hostname" elif [ "$(/etc/hostname fi } function debian_network_mailname() { local host="$1" [ -f /etc/mailname ] || touch /etc/mailname if [ -n "$__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS" ]; then uecho "Setting /etc/mailname to $host" elif [ "$(/etc/mailname fi } function debian_network_fix_exim4() { local host="$1" oldhost="$2" local tmpfile; ac_set_tmpfile tmpfile sed "$tmpfile" " /^dc_other_hostnames=/c\\ dc_other_hostnames='$host'" 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 debian_network_backup /etc/exim4/update-exim4.conf.conf if show_debug; then edebug "Setting /etc/exim4/update-exim4.conf.conf to:" cat "$tmpfile" | sed 's/^/ /g' 1>&2 else estep /etc/exim4/update-exim4.conf.conf fi cat "$tmpfile" >/etc/exim4/update-exim4.conf.conf update-exim4.conf fi ac_clean "$tmpfile" } function debian_network_fix_postfix() { local host="$1" oldhost="$2" local tmpfile; ac_set_tmpfile tmpfile awkrun "$tmpfile" host="$host" oldhost="$oldhost" ' /^myhostname *=/ { $0 = "myhostname = " host } /^mydestination *=/ { gsub(" *" oldhost " *,? *", "") if ($0 !~ (" *" host " *,? *")) { sub(/^mydestination *= */, "mydestination = " host ", ") } } { print }' if [ -n "$__DEBIAN_NETWORK_DEVEL_SHOW_MODIFS" ]; then if testdiff "$tmpfile" /etc/postfix/main.cf; then uecho "Setting /etc/postfix/main.cf to:" cat "$tmpfile" | sed 's/^/ /g' 1>&2 else uecho "/etc/postfix/main.cf: pas de modifications" fi elif testdiff "$tmpfile" /etc/postfix/main.cf; then debian_network_backup /etc/postfix/main.cf if show_debug; then edebug "Setting /etc/postfix/main.cf to:" cat "$tmpfile" | sed 's/^/ /g' 1>&2 else estep /etc/postfix/main.cf fi cat "$tmpfile" >/etc/postfix/main.cf fi ac_clean "$tmpfile" } function debian_network_hosts() { local host="$1" hostname="${1%%.*}" ip="$2" local shost="${host//./\\.}" local tmpfile; ac_set_tmpfile tmpfile awkrun "$tmpfile" host="$host" hostname="$hostname" ip="$ip" ' /^[^# \t]/ { gsub("[ \\t]+" host "[ \\t]*", " ") gsub("[ \\t]+" hostname "[ \\t]*", " ") if ($0 ~ /^[^ \t]+[ \t]*$/) next gsub(/[ \t]*$/, "") } { print }' local sip="${ip//./\\.}" shost="${host//./\\.}" if ! quietgrep "^$sip[ $TAB]\\+$shost[ $TAB]\\+$hostname" "$tmpfile"; then sed -i "/^$sip[ $TAB]/d" "$tmpfile" sed -i "1i\\ $ip$TAB$host $hostname" "$tmpfile" fi 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 debian_network_backup /etc/hosts if show_debug; then edebug "Setting /etc/hosts to:" cat "$tmpfile" | sed 's/^/ /g' 1>&2 else estep /etc/hosts fi cat "$tmpfile" >/etc/hosts fi ac_clean "$tmpfile" } function debian_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 debian_network_parse_ipspec() { # ipspec --> ip suffix gateway local __npi_tmp splitfsep "$1" / "${2:-ip}" __npi_tmp splitfsep "$__npi_tmp" + "${3:-suffix}" "${4:-gateway}" } function debian_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 debian_network_fix_confips() { # confips@ local -a __nfc_confips __nfc_ipspecs __nfc_ifaces __nfc_ips local __nfc_confip __nfc_iface __nfc_ipspec __nfc_ip __nfc_suffix __nfc_gateway __nfc_first array_copy __nfc_confips "${1:-confips}" # recenser les interfaces et créer les tableaux __IFACE_ipspecs for __nfc_confip in "${__nfc_confips[@]}"; do debian_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 __nfc_confip in "${__nfc_confips[@]}"; do debian_network_parse_confip "$__nfc_confip" __nfc_iface __nfc_ipspecs for __nfc_ipspec in "${__nfc_ipspecs[@]}"; do debian_network_parse_ipspec "$__nfc_ipspec" __nfc_ip __nfc_suffix __nfc_gateway if ! array_contains __nfc_ips "$__nfc_ip"; then [ -n "$__nfc_suffix" ] || __nfc_suffix=24 if [ -z "$__nfc_gateway" ] && array_isempty "__nfc_${__nfc_iface}_ipspecs"; then # premier ipspec, il faut spécifier le gateway __nfc_gateway="$(ipcalc_gateway "$__nfc_ip" "$__nfc_suffix")" fi eval "array_add __nfc_${__nfc_iface}_ipspecs \"$__nfc_ip/$__nfc_suffix${__nfc_gateway:++$__nfc_gateway}\"" array_add __nfc_ips "$__nfc_ip" fi done done # puis construire le tableau final 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:-confips}" __nfc_confips } function debian_network_fix_confbrs() { # confbrs@ local -a __nfc_confbrs __nfc_ifaces __nfc_brs __nfc_ips local __nfc_confbr __nfc_br __nfc_iface __nfc_ip __nfc_suffix __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 debian_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 __nfc_confbr in "${__nfc_confbrs[@]}"; do debian_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 __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}" __nfc_confbrs } function debian_network_resolve_mainiface() { local __nrm_mainiface="${1:-mainiface}" __nrm_mainconfbr="$2" __nrm_mainconfip="$3" [ -n "${!__nrm_mainiface}" ] || debian_network_parse_confbr "$__nrm_mainconfbr" "$__nrm_mainiface" [ -n "${!__nrm_mainiface}" ] || debian_network_parse_confip "$__nrm_mainconfip" "$__nrm_mainiface" [ -n "${!__nrm_mainiface}" ] || set_var "$__nrm_mainiface" eth0 } function debian_network_set_confip() { eval "$(ip addr show dev "$1" | awk "BEGIN { mainipvar = \"${2:-mainip}\" supplipsvar = \"${3:-supplips}\" "' print mainipvar "=" print supplipsvar "=()" mainip = "" supplips = 0 } $1 == "inet" { if (mainip == "") { mainip = $2 print mainipvar "=\"" mainip "\"" } else { if (!supplips) { supplips = 1 print supplipsvar "=(" } print "\"" $2 "\"" } } END { if (supplips) { print ")" } }')" set_var "$2" "$(array_join "$2" ,)" } function debian_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 "\"" }')" } #BUG)" function debian_network_set_confips() { local -a __nsc_confips __nsc_ifaces __nsc_supplips local __nsc_iface __nsc_mainip __nsc_gateway array_from_lines __nsc_ifaces "$(ip link | grep -v '<.*LOOPBACK.*>' | grep '<.*UP.*>' | awk '{ sub(/:$/, "", $2); print $2}')" for __nsc_iface in "${__nsc_ifaces[@]}"; do debian_network_set_confip "$__nsc_iface" __nsc_mainip __nsc_supplips [ -n "$__nsc_mainip" ] || continue debian_network_set_gateway "$__nsc_iface" __nsc_gateway array_add __nsc_confips "$__nsc_iface:$__nsc_mainip${__nsc_gateway:++$__nsc_gateway}${__nsc_supplips:+,$__nsc_supplips}" done array_copy "${1:-confips}" __nsc_confips } function debian_network_set_confbrs() { local -a __nsc_ifaces __nsc_tmpconfbrs __nsc_confbrs local __nsc_confbr __nsc_br __nsc_iface array_from_lines __nsc_ifaces "$(ip link | grep -v '<.*LOOPBACK.*>' | grep '<.*UP.*>' | awk '{ sub(/:$/, "", $2); print $2}')" array_from_lines __nsc_tmpconfbrs "$(brctl show 2>/dev/null | awk 'BEGIN { br = "" } NR == 1 { next } $1 != "" { br = $1 } { print br ":" $4 } ')" for __nsc_confbr in "${__nsc_tmpconfbrs[@]}"; do splitpair "$__nsc_confbr" __nsc_br __nsc_iface array_contains __nsc_ifaces "$__nsc_br" || continue array_add __nsc_confbrs "$__nsc_confbr" done array_copy "${1:-confbrs}" __nsc_confbrs } __DEBIAN_NETWORK_UPDATE_BASE_SCRIPT=' BEGIN { method = "dhcp" array_new(have_iface_hotplugs) array_new(have_iface_autos) array_new(have_iface_manuals) array_new(ips) array_new(suffixes) array_new(gateways) array_new(have_ip_ups) array_new(have_ip_downs) } function indexof_iface(iface, i) { for (i = 1; i <= ifaces_count; i++) { if (ifaces[i] == iface) { return i } } return 0 } function indexof_ip(ip, i) { for (i = 1; i <= ipspecs_count; i++) { if (ips[i] == ip) { return i } } return 0 } function get_netmask(suffix) { if (suffix == 0) return "0.0.0.0" else if (suffix == 8) return "255.0.0.0" else if (suffix == 16) return "255.255.0.0" else if (suffix == 24) return "255.255.255.0" else if (suffix == 32) return "255.255.255.255" else return suffix } function remove_hotplug_iface(iface, line) { if (line == "") line = $0 if (line !~ / $/) line = line " " gsub(" " iface " ", " ", line) return line } function print_hotplug_iface(line) { if (line ~ /^allow-hotplug *$/) { # une seule interface sur la ligne: ne pas l"afficher } else { # supprimer l"interface de la ligne sub(/ *$/, "", line) print line } } function remove_auto_iface(iface, line) { if (line == "") line = $0 " " gsub(" " iface " ", " ", line) return line } function print_auto_iface(line) { if (line ~ /^(allow-)?auto *$/) { # une seule interface sur la ligne: ne pas l"afficher } else { # supprimer l"interface de la ligne sub(/ *$/, "", line) print line } } ' __DEBIAN_NETWORK_UPDATE_BRIDGE_SCRIPT=' BEGIN { for (i = 1; i <= ifaces_count; i++) { have_iface_hotplugs[i] = 0 have_iface_autos[i] = 0 have_iface_manuals[i] = 0 } for (i = 1; i <= ipspecs_count; i++) { if (match(ipspecs[i], "^([^/]*)(/([^+]*))?(\\+(.*))?$", vs) != 0) { ip = vs[1] suffix = vs[3] gateway = vs[5] } else { ip = "" suffix = "" gateway = "" } if (i == 1) { if (ip == "dhcp") { method = "dhcp" } else { method = "static" mainip = ip } } if (suffix == "") suffix = "24" ips[i] = ip suffixes[i] = suffix gateways[i] = gateway have_ip_ups[i] = i == 1 have_ip_downs[i] = i == 1 } } ' __DEBIAN_NETWORK_UPDATE_IFACE_SCRIPT=' BEGIN { for (i = 1; i <= ipspecs_count; i++) { if (match(ipspecs[i], "^([^/]*)(/([^+]*))?(\\+(.*))?$", vs) != 0) { ip = vs[1] suffix = vs[3] gateway = vs[5] } else { ip = "" suffix = "" gateway = "" } if (i == 1) { if (ip == "dhcp") { method = "dhcp" } else { method = "static" mainip = ip } } if (suffix == "") suffix = "24" ips[i] = ip suffixes[i] = suffix gateways[i] = gateway have_ip_ups[i] = i == 1 have_ip_downs[i] = i == 1 } } ' function debian_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. local inf="$1"; shift local outf="$1"; shift awkrun <"$inf" -f iface="$1" ipspecs[@]="${2:-ipspecs}" ifaces[@]="${3:-ifaces}" ' BEGIN { have_hotplug = 0 have_auto = 0 have_iface = 0 have_method = 0 # static ou dhcp in_iface = 0 have_mainip = 0 } '" $__DEBIAN_NETWORK_UPDATE_BASE_SCRIPT $__DEBIAN_NETWORK_UPDATE_BRIDGE_SCRIPT "' $1 == "iface" && $2 == iface && $3 == "inet" { have_iface = 1 if (($0 " ") ~ (" " method " ")) have_method = 1 in_iface = 1 next } in_iface && ($0 " ") ~ "^[ \\t]*address " mainip " " { have_mainip = 1 } in_iface && $0 ~ "^[ \\t]*up (/sbin/)?ip addr add " { if (match($0, "ip addr add (.*)/.* dev " iface, vs) != 0) { i = indexof_ip(vs[1]) if (i != 0) have_ip_ups[i] = 1 } next } in_iface && $0 ~ "^[ \\t]*down (/sbin/)?ip addr del " { if (match($0, "ip addr del (.*)/.* dev " iface, vs) != 0) { i = indexof_ip(vs[1]) if (i != 0) have_ip_downs[i] = 1 } next } $1 == "iface" { i = indexof_iface($2) if (i != 0 && $3 == "inet" && $4 == "manual") { have_iface_manuals[i] = 1 } in_iface = 0 next } $1 == "allow-hotplug" { if (($0 " ") ~ (" " iface " ")) have_hotplug = 1 for (i = 1; i <= ifaces_count; i++) { if (($0 " ") ~ (" " ifaces[i] " ")) iface_have_hotplugs[i] = 1 } in_iface = 0 next } $1 ~ /^(allow-)?auto$/ { if (($0 " ") ~ (" " iface " ")) have_auto = 1 for (i = 1; i <= ifaces_count; i++) { if (($0 " ") ~ (" " ifaces[i] " ")) have_iface_autos[i] = 1 } in_iface = 0 next } END { check_hotplug = !have_hotplug if (check_hotplug) for (i = 1; i <= ifaces_count; i++) { if (iface_have_hotplugs[i]) { check_hotplug = 0 break } } check_auto = have_auto if (check_auto) for (i = 1; i <= ifaces_count; i++) { if (!have_iface_autos[i]) { check_auto = 0 break } } check_iface = have_iface && have_method && have_mainip check_supplips = 1 for (i = 1; i <= ipspecs_count; i++) { if (!have_ip_ups[i] || !have_ip_downs[i]) { check_supplips = 0 break } } if (!check_hotplug || !check_auto || !check_iface || !check_supplips) { exit 1 # il faut refaire la configuration } exit 0 # tout est ok } ' && return 1 # il faut refaire la configuration awkrun <"$inf" >"$outf" -f iface="$1" ipspecs[@]="${2:-ipspecs}" ifaces[@]="${3:-ifaces}" ' BEGIN { have_auto = 0 remove_auto = 0 array_new(remove_iface_autos) for (i = 1; i <= ifaces_count; i++) { remove_iface_autos[i] = 0 } replace_conf = 1 in_iface = 0 found_iface = 0 remove_old_iface = 0 } '" $__DEBIAN_NETWORK_UPDATE_BASE_SCRIPT $__DEBIAN_NETWORK_UPDATE_BRIDGE_SCRIPT "' function write_conf() { replace_conf = 0 for (i = 1; i <= ifaces_count; i++) { printed = 0 if (!have_iface_autos[i]) { print "auto " ifaces[i] printed = 1 } if (!have_iface_manuals[i]) { print "iface " ifaces[i] " inet manual" printed = 1 } if (printed) print "" } if (!have_auto) print "auto " iface print "iface " iface " inet " method if (ipspecs_count > 0 && method == "static") { print " address " ips[1] print " netmask " get_netmask(suffixes[1]) if (gateways[1] != "" && gateways[1] != ips[1]) { print " gateway " gateways[1] } } ports = " bridge_ports" if (ifaces_count == 0) { ports = ports " none" } else { for (i = 1; i <= ifaces_count; i++) { ports = ports " " ifaces[i] } } print ports print " bridge_stp off" print " bridge_fd 2" print " bridge_maxwait 0" serial = 0 for (i = 2; i <= ipspecs_count; i++) { print " up ip addr add " ips[i] "/" suffixes[i] " dev " iface " label " iface ":" serial print " down ip addr del " ips[i] "/" suffixes[i] " dev " iface " label " iface ":" serial serial++ } print "" } remove_old_iface && $1 == "iface" { remove_old_iface = 0 } !remove_old_iface && replace_conf && !in_iface && $1 == "iface" && $2 == iface && $3 == "inet" { in_iface = 1 found_iface = 1 next } !remove_old_iface && $1 == "iface" { in_iface = 0 for (i = 1; i <= ifaces_count; i++) { if ($2 == ifaces[i]) { if ($3 == "inet" && $4 == "manual") { have_iface_manuals[i] = 1 break } else { remove_old_iface = 1 } } } if (replace_conf && found_iface) write_conf() if (!remove_old_iface) print next } $1 == "allow-hotplug" { in_iface = 0 remove_old_iface = 0 if (replace_conf && found_iface) write_conf() line = $0 if (($0 " ") ~ (" " iface " ")) line = remove_hotplug_iface(iface, line) for (i = 1; i <= ifaces_count; i++) { if (($0 " ") ~ (" " ifaces[i] " ")) line = remove_hotplug_iface(ifaces[i], line) } print_hotplug_iface(line) next } $1 ~ /(allow-)?auto/ { in_iface = 0 remove_old_iface = 0 if (replace_conf && found_iface) write_conf() line = $0 if (($0 " ") ~ (" " iface " ")) { if (!remove_auto) { have_auto = 1 remove_auto = 1 } else { line = remove_auto_iface(iface, line) } } for (i = 1; i <= ifaces_count; i++) { if (($0 " ") ~ (" " ifaces[i] " ")) { if (!remove_iface_autos[i]) { have_iface_autos[i] = 1 remove_iface_autos[i] = 1 } else { line = remove_auto_iface(ifaces[i], line) } } } print_auto_iface(line) next } { print } END { if (replace_conf) write_conf() } ' return 0 } function debian_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. local inf="$1"; shift local outf="$1"; shift awkrun <"$inf" -f iface="$1" ipspecs[@]="${2:-ipspecs}" ' BEGIN { have_hotplug = 0 have_auto = 0 have_iface = 0 have_method = 0 # static ou dhcp in_iface = 0 have_mainip = 0 } '" $__DEBIAN_NETWORK_UPDATE_BASE_SCRIPT $__DEBIAN_NETWORK_UPDATE_IFACE_SCRIPT "' $1 == "iface" && $2 == iface && $3 == "inet" { have_iface = 1 if (($0 " ") ~ (" " method " ")) have_method = 1 in_iface = 1 next } in_iface && ($0 " ") ~ "^[ \\t]*address " mainip " " { have_mainip = 1 } in_iface && $0 ~ "^[ \\t]*up (/sbin/)?ip addr add " { if (match($0, "ip addr add (.*)/.* dev " iface, vs) != 0) { i = indexof_ip(vs[1]) if (i != 0) have_ip_ups[i] = 1 } next } in_iface && $0 ~ "^[ \\t]*down (/sbin/)?ip addr del " { if (match($0, "ip addr del (.*)/.* dev " iface, vs) != 0) { i = indexof_ip(vs[1]) if (i != 0) have_ip_downs[i] = 1 } next } $1 == "iface" { in_iface = 0 next } $1 == "allow-hotplug" { if (($0 " ") ~ (" " iface " ")) have_hotplug = 1 in_iface = 0 next } $1 ~ /^(allow-)?auto$/ { if (($0 " ") ~ (" " iface " ")) have_auto = 1 in_iface = 0 next } END { check_hotplug = !have_hotplug check_auto = have_auto check_iface = have_iface && have_method && have_mainip check_supplips = 1 for (i = 1; i <= ipspecs_count; i++) { if (!have_ip_ups[i] || !have_ip_downs[i]) { check_supplips = 0 break } } if (!check_hotplug || !check_auto || !check_iface || !check_supplips) { exit 1 # il faut refaire la configuration } exit 0 # tout est ok } ' && return 1 # il faut refaire la configuration awkrun <"$inf" >"$outf" -f iface="$1" ipspecs[@]="${2:-ipspecs}" ' BEGIN { have_auto = 0 remove_auto = 0 replace_conf = 1 in_iface = 0 found_iface = 0 } '" $__DEBIAN_NETWORK_UPDATE_BASE_SCRIPT $__DEBIAN_NETWORK_UPDATE_IFACE_SCRIPT "' function write_conf() { replace_conf = 0 if (!have_auto) print "auto " iface print "iface " iface " inet " method if (ipspecs_count > 0 && method == "static") { print " address " ips[1] print " netmask " get_netmask(suffixes[1]) if (gateways[1] != "" && gateways[1] != ips[1]) { print " gateway " gateways[1] } } serial = 0 for (i = 2; i <= ipspecs_count; i++) { print " up ip addr add " ips[i] "/" suffixes[i] " dev " iface " label " iface ":" serial print " down ip addr del " ips[i] "/" suffixes[i] " dev " iface " label " iface ":" serial serial++ } print "" } ($0 " ") ~ ("^allow-hotplug.* " iface " ") { print_hotplug_iface(remove_hotplug_iface(iface)); next; } !remove_auto && ($0 " ") ~ ("^(allow-)?auto.* " iface " ") { have_auto = 1; remove_auto = 1; next; } remove_auto && ($0 " ") ~ ("^(allow-)?auto.* " iface " ") { print_auto_iface(remove_auto_iface(iface)); next; } replace_conf && !in_iface && $0 ~ ("^iface " iface " inet ") { in_iface = 1; found_iface = 1; next; } replace_conf && found_iface && in_iface && $0 ~ "^iface " { print; in_iface = 0; write_conf(); next; } { print } END { if (replace_conf) write_conf() } ' return 0 } function network_config() { # (Re)configurer le réseau sur l'hôte courant. # $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, c'est à dire # l'interface qui est sélectionnée si une adresse ip n'est pas préfixée de # son interface. En principe, l'interface principale est le premier bridge # défini ou la première interface définie. # $5 (reset_interfaces) spécifie de ne pas chercher à mettre à jour le # fichier /etc/network/interfaces, mais de le recréer depuis zéro. # Si un des arguments n'est pas spécifié, il est ignoré. # Le tableau confips doit contenir des définitions d'une des formes # suivantes: # [iface:]address[/suffix][+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_confips __nc_confbrs [ -n "$2" ] && array_copy __nc_confips "$2" [ -n "$3" ] && array_copy __nc_confbrs "$3" local host="$1" mainiface="$4" reset_interfaces="$5" local -a confips confbrs array_copy confips __nc_confips array_copy confbrs __nc_confbrs debian_network_fix_confips confips debian_network_fix_confbrs confbrs local mainbr # bridge principal local mainip # adresse IP principale de l'interface principale local confbr confip br iface suffix gateway local -a ipspecs debian_network_resolve_mainiface mainiface "${confbrs[0]}" "${confips[0]}" debian_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 debian_network_parse_confip "$confip" iface array_addu ifaces_with_ips "$iface" done for confbr in "${confbrs[@]}"; do debian_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 debian_network_parse_confip "$confip" iface [ -n "$iface" ] || iface="$mainiface" 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" if [ -n "$reset_interfaces" ]; then echo >"$interfaces" "\ # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface auto lo iface lo inet loopback " fi # configurer chaque bridge local -a tmpifaces local tmpbr for confip in "${confbrips[@]}"; do debian_network_parse_confip "$confip" br ipspecs [ -n "$br" ] || br="$mainbr" if [ -z "$mainip" -a "$br" == "$mainiface" ]; then debian_network_parse_ipspec "${ipspecs[0]}" mainip suffix gateway fi ifaces=() for confbr in "${confbrs[@]}"; do debian_network_parse_confbr "$confbr" tmpbr tmpifaces if [ "$tmpbr" == "$br" ]; then array_copy ifaces tmpifaces break fi done if debian_network_update_bridge "$interfaces" "$workfile" "$br" ipspecs ifaces; then cat "$workfile" >"$interfaces" fi done # configurer chaque interface classique for confip in "${confstdips[@]}"; do debian_network_parse_confip "$confip" iface ipspecs [ -n "$iface" ] || iface="$mainiface" if [ -z "$mainip" -a "$iface" == "$mainiface" ]; then debian_network_parse_ipspec "${ipspecs[0]}" mainip suffix gateway fi if debian_network_update_iface "$interfaces" "$workfile" "$iface" ipspecs; then cat "$workfile" >"$interfaces" fi 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 debian_network_backup /etc/network/interfaces if show_debug; then edebug "Setting /etc/network/interfaces to:" cat "$interfaces" | sed 's/^/ /g' 1>&2 else estep /etc/network/interfaces fi cat "$interfaces" >/etc/network/interfaces fi ac_clean "$interfaces" "$workfile" eend fi # configurer le nom d'hôte if [ -n "$host" ]; then host="$(ipcalc_fqdn_maybe "$host")" etitle "Configuration du nom d'hôte: $host" # si on ne spécifie pas l'adresse ip principale, la résoudre ici. ceci # est nécessaire pour mettre à jour /etc/hosts 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 } mainip="${mainips[0]}" fi debian_network_hostname "$host" debian_network_mailname "$host" if [ -n "$mainip" ]; then debian_network_hosts "$host" "$mainip" fi eend fi return 0 }