From: intrigeri Date: Tue, 29 Nov 2005 10:10:08 +0000 (+0000) Subject: r3562@krups: intrigeri | 2005-11-16 20:20:16 +0100 X-Git-Url: https://git.stderr.nl/gitweb?a=commitdiff_plain;h=a61c0a8b4533b87ff86b4bafdd5216fc10abfa51;p=matthijs%2Fupstream%2Fbackupninja-vserver.git r3562@krups: intrigeri | 2005-11-16 20:20:16 +0100 Moved more code to lib/ (conffile-related functions, parseini. Added dup helper, using new modular vservers-related functions shared for all helpers. git-svn-id: http://code.autistici.org/svn/backupninja/trunk@246 758a04ac-41e6-0310-8a23-8373a73cc35d --- diff --git a/ChangeLog b/ChangeLog index 5d38854..a9b259a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ version 0.9.2 -- unreleased rdiff ninjahelper bugfixes: used to expand '*' in default source directories the "Cancel" buttons used to have a weird behaviour... at least + code refactor: moved to lib/ some code that has to be shared between + backupninja and ninjahelper + added duplicity ninjahelper version 0.9.1 -- November 05 2005 rearranged source so that it is relocatable with autotools diff --git a/handlers/Makefile.am b/handlers/Makefile.am index dbe453d..6ba0925 100644 --- a/handlers/Makefile.am +++ b/handlers/Makefile.am @@ -1,10 +1,8 @@ -HANDLERS = dup dup.helper maildir mysql.helper rdiff sys \ - makecd makecd.helper \ - parseini rdiff.helper sys.helper ldap pgsql sh trac \ +HANDLERS = dup dup.helper maildir mysql.helper rdiff sys makecd makecd.helper \ + rdiff.helper sys.helper ldap pgsql sh trac \ ldap.helper mysql pgsql.helper svn - EXTRA_DIST = Makefile.am $(HANDLERS) dist_pkgdata_DATA = $(HANDLERS) diff --git a/handlers/Makefile.in b/handlers/Makefile.in index df6dd3e..18e02ef 100644 --- a/handlers/Makefile.in +++ b/handlers/Makefile.in @@ -112,9 +112,8 @@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ HANDLERS = dup dup.helper maildir mysql.helper rdiff sys \ - makecd makecd.helper \ - parseini rdiff.helper sys.helper ldap pgsql sh trac \ - ldap.helper mysql pgsql.helper svn + makecd makecd.helper rdiff.helper sys.helper \ + ldap pgsql sh trac ldap.helper mysql pgsql.helper svn EXTRA_DIST = Makefile.am $(HANDLERS) dist_pkgdata_DATA = $(HANDLERS) diff --git a/handlers/dup.helper b/handlers/dup.helper index 7c172f0..89f458d 100644 --- a/handlers/dup.helper +++ b/handlers/dup.helper @@ -61,7 +61,7 @@ do_dup_excludes() { } do_dup_src() { - host_or_vservers_chooser + host_or_vservers_chooser "$dup_title" [ $? = 0 ] || return 1 case $host_or_vservers in 'host') diff --git a/handlers/parseini b/handlers/parseini deleted file mode 100644 index 6f56d42..0000000 --- a/handlers/parseini +++ /dev/null @@ -1,130 +0,0 @@ -# -# parseini --- parses 'ini' style configuration files. -# -# Usage: -# awk -f parseini S=
P= -# -# if section is an empty string, then we use the default section -# -# example ini file: -# -# fruit = apple -# fruit = pear -# multiline = this is a multiline \ -# parameter -# -# # this is a comment -# -# [colors] -# red = yes -# green = no -# blue = maybe -# -# [ocean] -# fish = red -# fish = blue -# -# example usage: -# > awk -f parseini S=ocean P=fish testfile.ini -# would return: -# red -# blue -# - -BEGIN { - readlines = 1 - implied = 1 -} - -# remove lines starting with #, but not #! -/^#[^!]/ {next} - -# skip blank -/^[ \r\t]*$/ {next} - -# we want to read the lines of the matched section -# and disable for other sections -/^\[.+\][ \r\t]*$/ { - continueline = 0 - if (S && implied) { - nline = 0 - implied = 0 - } - if (S && match($0, "^\\[" S "\\][ \n]*")) { - # we found the section, so start reading. - readlines = 1 - } - else { - # no section, so stop reading lines - if (readlines) readlines = 0 - } - next -} - -# when reading, store lines. - -{ - if (!readlines) next - line[nline++] = $0 - if ($0 ~ /\\[ \r\t]*$/) - continueline = 1 - else - continueline = 0 -} - -# process the read lines lines, matching parameters - -END { - # if section is set but implied is still true - # then we never found the section, so use everything - if (S && implied) { - nline = 0 - } - - # if have P then find P in read lines and get values - if (P) { - MATCH = "^[ \r\t]*" P "[ \r\t]*=" - continueline = 0 - for (x = 0; x < nline; ++x) { - v = line[x] - if (continueline) { - sub(/[ \r\t]+$/, "", v) - if (v ~ /\\$/) { - v = substr(v, 1, length(v)-1) - sub(/[ \r\t]+$/, "", v) - } - if (v) value[nvalue++] = v - } - else if (v ~ MATCH) { - sub(MATCH, "", v) - sub(/^[ \r\t]+/, "", v) - sub(/[ \r\t]+$/, "", v) - if (v ~ /\\$/) { - continueline = 1 - v = substr(v, 1, length(v)-1) - sub(/[ \r\t]+$/, "", v) - } - if (v) value[nvalue++] = v - } - } - # copy parameter definition to output array - nline = nvalue - for (x = 0; x < nvalue; ++x) - line[x] = value[x] - } - - # trim all leading & trailing whitespace; - # except for leading whitespace in continuation lines, - - for (x = 0; x < nline; ++x) { - sub(/^[ \r\t]+/, "", line[x]) - sub(/[ \r\t]+$/, "", line[x]) - } - - # output the final result - for (x = 0; x < nline; ++x) - print line[x] - - if (nline) exit 0 - else exit 1 -} diff --git a/lib/Makefile.am b/lib/Makefile.am index 2fcce96..08c26c7 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,15 +1,22 @@ -EXTRALIBS = easydialog tools -CLEANFILES = $(EXTRALIBS) -dist_pkglib_DATA = $(EXTRALIBS) -EXTRA_DIST = easydialog.in tools.in +EXTRA_DIST = easydialog.in parseini.in tools.in + +GENERATED_FILES = easydialog parseini tools + +dist_pkglib_DATA = $(GENERATED_FILES) + +CLEANFILES = $(GENERATED_FILES) edit = sed \ -e "s,@BASH\@,$(BASH),g" -easydialog: easydialog.in +easydialog: #easydialog.in rm -f easydialog $(edit) easydialog.in > easydialog -tools: tools.in +parseini: #parseini.in + rm -f parseini + $(edit) parseini.in > parseini + +tools: #tools.in rm -f tools $(edit) tools.in > tools diff --git a/lib/Makefile.in b/lib/Makefile.in index 8ce67a9..3da86b9 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -111,10 +111,10 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -EXTRALIBS = easydialog tools -CLEANFILES = $(EXTRALIBS) -dist_pkglib_DATA = $(EXTRALIBS) -EXTRA_DIST = easydialog.in tools.in +EXTRA_DIST = easydialog.in parseini.in tools.in +GENERATED_FILES = easydialog parseini tools +dist_pkglib_DATA = $(GENERATED_FILES) +CLEANFILES = $(GENERATED_FILES) edit = sed \ -e "s,@BASH\@,$(BASH),g" @@ -291,11 +291,15 @@ uninstall-am: uninstall-dist_pkglibDATA uninstall-info-am uninstall-dist_pkglibDATA uninstall-info-am -easydialog: easydialog.in +easydialog: #easydialog.in rm -f easydialog $(edit) easydialog.in > easydialog -tools: tools.in +parseini: #parseini.in + rm -f parseini + $(edit) parseini.in > parseini + +tools: #tools.in rm -f tools $(edit) tools.in > tools # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/lib/parseini.in b/lib/parseini.in new file mode 100644 index 0000000..6f56d42 --- /dev/null +++ b/lib/parseini.in @@ -0,0 +1,130 @@ +# +# parseini --- parses 'ini' style configuration files. +# +# Usage: +# awk -f parseini S=
P= +# +# if section is an empty string, then we use the default section +# +# example ini file: +# +# fruit = apple +# fruit = pear +# multiline = this is a multiline \ +# parameter +# +# # this is a comment +# +# [colors] +# red = yes +# green = no +# blue = maybe +# +# [ocean] +# fish = red +# fish = blue +# +# example usage: +# > awk -f parseini S=ocean P=fish testfile.ini +# would return: +# red +# blue +# + +BEGIN { + readlines = 1 + implied = 1 +} + +# remove lines starting with #, but not #! +/^#[^!]/ {next} + +# skip blank +/^[ \r\t]*$/ {next} + +# we want to read the lines of the matched section +# and disable for other sections +/^\[.+\][ \r\t]*$/ { + continueline = 0 + if (S && implied) { + nline = 0 + implied = 0 + } + if (S && match($0, "^\\[" S "\\][ \n]*")) { + # we found the section, so start reading. + readlines = 1 + } + else { + # no section, so stop reading lines + if (readlines) readlines = 0 + } + next +} + +# when reading, store lines. + +{ + if (!readlines) next + line[nline++] = $0 + if ($0 ~ /\\[ \r\t]*$/) + continueline = 1 + else + continueline = 0 +} + +# process the read lines lines, matching parameters + +END { + # if section is set but implied is still true + # then we never found the section, so use everything + if (S && implied) { + nline = 0 + } + + # if have P then find P in read lines and get values + if (P) { + MATCH = "^[ \r\t]*" P "[ \r\t]*=" + continueline = 0 + for (x = 0; x < nline; ++x) { + v = line[x] + if (continueline) { + sub(/[ \r\t]+$/, "", v) + if (v ~ /\\$/) { + v = substr(v, 1, length(v)-1) + sub(/[ \r\t]+$/, "", v) + } + if (v) value[nvalue++] = v + } + else if (v ~ MATCH) { + sub(MATCH, "", v) + sub(/^[ \r\t]+/, "", v) + sub(/[ \r\t]+$/, "", v) + if (v ~ /\\$/) { + continueline = 1 + v = substr(v, 1, length(v)-1) + sub(/[ \r\t]+$/, "", v) + } + if (v) value[nvalue++] = v + } + } + # copy parameter definition to output array + nline = nvalue + for (x = 0; x < nvalue; ++x) + line[x] = value[x] + } + + # trim all leading & trailing whitespace; + # except for leading whitespace in continuation lines, + + for (x = 0; x < nline; ++x) { + sub(/^[ \r\t]+/, "", line[x]) + sub(/[ \r\t]+$/, "", line[x]) + } + + # output the final result + for (x = 0; x < nline; ++x) + print line[x] + + if (nline) exit 0 + else exit 1 +} diff --git a/lib/tools.in b/lib/tools.in index 89f2ff7..90df264 100644 --- a/lib/tools.in +++ b/lib/tools.in @@ -1,5 +1,9 @@ #!@BASH@ +# This file contains functions shared between ninjahelper and backupninja. + +##################################################### +## MISC FUNCTIONS # # create a temporary file in a secure way. @@ -16,4 +20,35 @@ function maketemp() { echo $tempfile } +##################################################### +## CONFIG-FILE RELATED FUNCTIONS + +function setfile() { + CURRENT_CONF_FILE=$1 +} + +function setsection() { + CURRENT_SECTION=$1 +} + +# +# sets a global var with name equal to $1 +# to the value of the configuration parameter $1 +# $2 is the default. +# +function getconf() { + CURRENT_PARAM=$1 + ret=`awk -f $libdirectory/parseini S=$CURRENT_SECTION P=$CURRENT_PARAM $CURRENT_CONF_FILE` + # if nothing is returned, set the default + if [ "$ret" == "" -a "$2" != "" ]; then + ret="$2" + fi + # replace * with %, so that it is not globbed. + ret="${ret//\\*/__star__}" + + # this is weird, but single quotes are needed to + # allow for returned values with spaces. $ret is still expanded + # because it is in an 'eval' statement. + eval $1='$ret' +} diff --git a/src/backupninja.in b/src/backupninja.in index 2663457..f43eaab 100755 --- a/src/backupninja.in +++ b/src/backupninja.in @@ -121,38 +121,6 @@ function msg { let "msgcount += 1" } -function setfile() { - CURRENT_CONF_FILE=$1 -} - -function setsection() { - CURRENT_SECTION=$1 -} - - -# -# sets a global var with name equal to $1 -# to the value of the configuration parameter $1 -# $2 is the default. -# - -function getconf() { - CURRENT_PARAM=$1 - ret=`awk -f $scriptdir/parseini S=$CURRENT_SECTION P=$CURRENT_PARAM $CURRENT_CONF_FILE` - # if nothing is returned, set the default - if [ "$ret" == "" -a "$2" != "" ]; then - ret="$2" - fi - - # replace * with %, so that it is not globbed. - ret="${ret//\\*/__star__}" - - # this is weird, but single quotes are needed to - # allow for returned values with spaces. $ret is still expanded - # because it is in an 'eval' statement. - eval $1='$ret' -} - # # enforces very strict permissions on configuration file $file. # @@ -308,7 +276,7 @@ function process_action() { echo "" > $bufferfile echo_debug_msg=1 ( - . $scriptdir/$suffix $file + . $scriptdirectory/$suffix $file ) 2>&1 | ( while read a; do echo $a >> $bufferfile @@ -408,42 +376,30 @@ if [ ! -r "$conffile" ]; then fatal "Configuration file $conffile not found." fi -# find $scriptdir -scriptdir=`grep scriptdirectory $conffile | awk '{print $3}'` -if [ -z "$scriptdir" ]; then - if [ -d "@datadir@" ]; then - scriptdir="@datadir@" - else - echo "Could not find entry 'scriptdirectory' in $conffile" - fatal "Could not find entry 'scriptdirectory' in $conffile" - fi -else - if [ ! -d "$scriptdir" ]; then - echo "Script directory $scriptdir not found." - fatal "Script directory $scriptdir not found." - fi -fi - -# find $libdir -libdir=`grep libdirectory $conffile | awk '{print $3}'` -if [ -z "$libdir" ]; then +# find $libdirectory +libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'` +if [ -z "$libdirectory" ]; then if [ -d "@libdir@" ]; then - libdir="@libdir@" + libdirectory="@libdir@" else echo "Could not find entry 'libdirectory' in $conffile." fatal "Could not find entry 'libdirectory' in $conffile." fi else - if [ ! -d "$libdir" ]; then - echo "Lib directory $libdir not found." - fatal "Lib directory $libdir not found." + if [ ! -d "$libdirectory" ]; then + echo "Lib directory $libdirectory not found." + fatal "Lib directory $libdirectory not found." fi fi +# include shared functions +. $libdirectory/tools + setfile $conffile # get global config options (second param is the default) getconf configdirectory @CFGDIR@/backup.d +getconf scriptdirectory @datadir@ getconf reportemail getconf reportsuccess yes getconf reportwarning yes @@ -472,9 +428,6 @@ if [ ! -d "$configdirectory" ]; then fatal "Configuration directory '$configdirectory' not found." fi -# include shared functions -. $libdir/tools - [ -f "$logfile" ] || touch $logfile if [ "$UID" != "0" ]; then @@ -516,7 +469,7 @@ for file in $files; do continue fi - if [ -e "$scriptdir/$suffix" ]; then + if [ -e "$scriptdirectory/$suffix" ]; then process_action $file $suffix else error "Can't process file '$file': no handler script for suffix '$suffix'" diff --git a/src/ninjahelper.in b/src/ninjahelper.in index 451f389..0d7050c 100755 --- a/src/ninjahelper.in +++ b/src/ninjahelper.in @@ -58,6 +58,8 @@ require_packages() { ## menu for the wizards ## donew() { + unset host_or_vservers + unset vservers_chooser_vsnames listBegin "new action menu" "select an action to create" listItem return "return to main menu" for data in $HELPERS; do @@ -162,6 +164,102 @@ doaction() { done } +##################################################### +## VSERVERS RELATED FUNCTIONS + +## +## If vservers are not enabled, exit silently and set host_or_vservers to 'host'. +## Else, have the user choose the target he/she wants to perform the backup on: +## - host system only +## - some vservers only +## - both the host system and some vservers +## Sets, respectively, $host_or_vservers to 'host', 'vservers', or 'both' +## $host_or_vservers is unset when a new helper is run. +## Returns 1 if cancelled. +## +host_or_vservers_chooser() { + local title=$1 + # exit silently if vservers are not enabled + if [ "$vservers" != "yes" ]; then + host_or_vservers='host' + return + fi + # if there is one, set the previously chosen item as the default + [ -n "$host_or_vservers" ] && setDefault $host_or_vservers + menuBox "$title - src" "Do you want to operate on the host system and/or on vservers?" \ + "host" "Host system only" \ + "vservers" "Vservers only" \ + "both" "Host system and Vservers" + [ $? = 0 ] || return 1 + case $REPLY in + "host") + host_or_vservers='host' + ;; + "vservers") + host_or_vservers='vservers' + ;; + "both") + host_or_vservers='both' + ;; + esac +} + +## +## If the argument is the name of a vserver selected for backup (in +## $vservers_chooser_vsnames), echoes 'on' and returns 0. +## Else, echoes 'off' and returns 1. +## +vserver_is_selected() { + local vserver=$1 + local vserver_is_selected=1 + local i + for i in $vservers_chooser_vsnames ; do + [ "$vserver" == "$i" ] && vserver_is_selected=0 + done + if [ $vserver_is_selected = 0 ]; then + echo on + else + echo off + fi + return $vserver_is_selected +} + +## +## Have the user choose among "all vservers" and a not-empty subset of these. +## Sets global $vservers_chooser_vsnames variable to "all" or to a +## space-separated name list. +## Depends on host_or_vservers() to have already run. +## $vservers_chooser_vsnames is unset when a new helper is run. +## Returns 1 if cancelled. +## +vservers_chooser() { + local title=$1 + local i= + [ -n "$VROOTDIR" ] || (msgBox "warning" "VROOTDIR is not set in $conffile and could not be guessed."; return 1) + [ -d "$VROOTDIR" ] || (msgBox "warning" "VROOTDIR ($VROOTDIR) does not exist."; return 1) + + booleanBox "$title" "Do you want to backup all vservers?" ` [ -z "$vservers_chooser_vsnames" -o "$vservers_chooser_vsnames" == "all" ] || echo no` + if [ $? = 0 ]; then + vservers_chooser_vsnames="all" + else + # choose among the existing vservers + local vserver= + local vserver_was_selected= + REPLY= + while [ -z "$REPLY" ]; do + listBegin "$title" "Choose at least one Linux-Vserver to backup:" + # list existing vservers, preselecting the previously selected ones + for vserver in `ls $VROOTDIR | grep -E -v "lost+found|ARCHIVES"`; do + listItem "$vserver" "Backup $vserver vserver" `vserver_is_selected $vserver` + done + listDisplay checklist + [ $? = 0 ] || return 1 + done + # remove quotes around each vserver name + vservers_chooser_vsnames=`echo $REPLY | tr -d '"'` + fi +} + ##################################################### ## begin program @@ -182,64 +280,51 @@ if [ ! -x "`which dialog`" ]; then done fi +# bootstrap conffile="@CFGDIR@/backupninja.conf" if [ ! -r "$conffile" ]; then echo "Configuration file $conffile not found." exit 1 fi -# find $scriptdir -scriptdir=`grep scriptdirectory $conffile | awk '{print $3}'` -if [ -z "$scriptdir" ]; then - if [ -d "@datadir@" ]; then - scriptdir="@datadir@" - else - echo "Could not find entry 'scriptdirectory' in $conffile" - exit 1 - fi -else - if [ ! -d "$scriptdir" ]; then - echo "Script directory $scriptdir not found." - exit 1 - fi -fi - -# find $libdir -libdir=`grep libdirectory $conffile | awk '{print $3}'` -if [ -z "$libdir" ]; then +# find $libdirectory +libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'` +if [ -z "$libdirectory" ]; then if [ -d "@libdir@" ]; then - libdir="@libdir@" + libdirectory="@libdir@" else echo "Could not find entry 'libdirectory' in $conffile." exit 1 fi else - if [ ! -d "$libdir" ]; then - echo "Lib directory $libdir not found." + if [ ! -d "$libdirectory" ]; then + echo "Lib directory $libdirectory not found." exit 1 fi fi -configdirectory=`grep configdirectory $conffile | awk '{print $3}'` -if [ ! -n "$configdirectory" ]; then - echo "Cound not find entry 'configdirectory' in $conffile" - exit 1 -fi -if [ ! -d "$configdirectory" ]; then - echo "Configuration directory $configdirectory not found." - exit 1 -fi - -. $libdir/easydialog +# include shared functions +. $libdirectory/easydialog +. $libdirectory/tools +# am I running as root? if [ "$UID" != "0" ]; then - msgBox "warning" "ninjahelper must be run by root!" + msgBox "warning" "$0 must be run by root!" exit 1 fi +# get global config options (second param is the default) +setfile $conffile +getconf configdirectory @CFGDIR@/backup.d +getconf scriptdirectory @datadir@ +getconf vservers no +getconf VSERVERINFO /usr/sbin/vserver-info +getconf VSERVER /usr/sbin/vserver +getconf VROOTDIR `if [ -f "$VSERVERINFO" ]; then $VSERVERINFO info SYSINFO |grep vserver-Rootdir | awk '{print $2}'; fi` + # load all the helpers HELPERS="" -for file in `find $scriptdir -follow -name '*.helper'`; do +for file in `find $scriptdirectory -follow -name '*.helper'`; do check_perms $file . $file done