Programmering og de kreative løsninger
I et forsøg på at gøre opdateringer af jails automatiske, løb jeg ind i et mindre problem med sproget SH.
Billedet viser oprettelsen af en liste i SH.
SH bruges typisk til systemadministration, og er det eneste sprog som min jail-server understøtter. Så for ikke at skulle installere mere software på serveren, ville jeg foretrække en løsning med SH. Selv en kreativ en.
OK, så jeg har 2 lister: Én over kørende jails og én over hvilket jails der skal opdateres. Et punkt fra den ene liste bliver holdt op imod alle punkterne fra den anden, og er der et match, bliver det pågældende jail opdateret. Simpelt.
Min umiddelbare tanke var at lave en løs sammenlig imellem listerne
if [[ $(jls name) =~ ${auto[@]} ]];
Men det virker selvfølgelig ikke, for en if er ikke lavet til at tjekke mere end én ting. Og det gælder ikke kun i SH, men alle sprog. Der er brug for at bringe listen ind i et loop, køre over hvert element på den ene liste, for så at sammenligne med hvert element på den anden liste.
Men loops understøtter ikke to lister.
Løsningen? To loops.
# Populate $j_au first from the running jails for j_au in $(jls name); do # Then populate $up_au from the acl in the header for up_au in ${auto[@]}; do # If they match, the jail is updated if [[ "$j_au" = "$up_au" ]]; then up_jls "$j_au" fi done
Det ydre loop stiller hvert element (navnet på et jail) til rådighed i en variabel, som det indre loop så kan sammenligne med. Opstår der et match, bliver navnet på jail’et givet til funktionen up_jls, som opdaterer jail’et.
// Nicky
Det fulde script:
#!/usr/bin/env bash # # acl for jails to autoupdate declare -a auto=( "dns" "mx" "prx" "nt" "rc" "nc" "pa" "ma" "for" "fa" "dls" ) # # Function to update jails up_jls() { echo echo "Updates packagelist for $1" # If the pkgs list does not need upgrading, don't do anything pkg_out=$(pkg --jail $1 upgrade --dry-run) if [[ $pkg_out =~ "Your packages are up to date." ]]; then echo "Packages for $1 are up to date" else # Otherwise upgrade, remove unused deps and clear the pkg cache pkg --jail $1 upgrade --no-repo-update --yes pkg --jail $1 autoremove --yes pkg --jail $1 clean --all --yes if [[ "$1" == "prx" ]]; then # Only reload apache, if the jail is running the TTP service -j $1 apache24 reload else # All other jails services is restarted service -j $1 -R fi echo "All done for $1" fi sleep 2 } # # Evaluate given parameters, if any if [[ -n $1 ]]; then while [ $# -ne 0 ]; do p="$1" shift case "$p" in # Update all jls, no matter the acl -a|--all) for j in `jls name`; do up_jls "$j" done echo "All running jails has been updated" exit 0 ;; -h|--help) echo "With no parameters, all running jails on the acl in the header is updated" echo echo "-a or --all updates all running jails without regard to the acl" echo echo "-h or --help shows this text" echo echo "All other parameters are taken as jail names, and the jail is" echo " updated if a running jail is matching that name" echo echo "Peace out" exit 0 ;; # Test if parameter is a jail name and update it *) if [[ $(jls name) =~ "$p" ]]; then up_jls "$p" else echo "$p does not match a running jail" sleep 2 fi ;; esac done # And if no parameter was given, an autoupdate from the acl is done else # Populate $j_au first from the running jails for j_au in $(jls name); do # Then populate $up_au from the acl in the header for up_au in ${auto[@]}; do # If they match, the jail is updated if [[ "$j_au" = "$up_au" ]]; then up_jls "$j_au" fi done done fi # exit 0