#!@BASH@ #################################################### ## Functions function check_perms() { local file=$1 local perms=`ls -ld $file` group_w_perm=${perms:5:1} world_w_perm=${perms:8:1} if [ "$group_w_perm" == "w" -o "$world_w_perm" == "w" ]; then echo $perms echo "helper scripts must not be group or world writable! Dying on file $file" exit fi if [ `ls -ld $file | awk '{print $3}'` != "root" ]; then echo "helper scripts must be owned by root! Dying on file $file" exit fi } ## ## returns the next available file name given a file ## in the form @CFGDIR@/backup.d/10.sys ## sets variable $next_filename ## get_next_filename() { next_filename=$1 dir=`dirname $next_filename` file=`basename $next_filename` number=${file:0:2} suffix=${file:3} while [ -f $next_filename ]; do let "number += 1" next_filename="$dir/$number.$suffix" done } ## ## installs packages (passed in as $@) if not present ## require_packages() { for pkg in "$@"; do installed=`dpkg -s $pkg | grep 'ok installed'` if [ -z "$installed" ]; then booleanBox "install $pkg?" "This backup action requires package $pkg. Do you want to install it now?" if [ $? = 0 ]; then apt-get install $pkg echo "hit return to continue...." read fi fi done } ## ## 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 data=${data//_/ } helper_function=${data%%:*} helper_info=${data##*:} listItem $helper_function "$helper_info" done listDisplay menu [ $? = 1 ] && return result="$REPLY" [ "$result" = "return" ] && return result=${result}_wizard $result } do_rm_action() { booleanBox "remove action" "Are you sure you want to remove action file $1?" if [ $? = 0 ]; then rm $1; fi } do_run() { backupninja --run $1 echo "Hit return to continue..." read } do_xedit() { if [ -z "$EDITOR" -o ! -x "`which $EDITOR`" ]; then if [ -h /etc/alternatives/editor -a -x "`readlink /etc/alternatives/editor`" ]; then EDITOR="`readlink /etc/alternatives/editor`" elif [ -x "`which nano`" ]; then EDITOR="`which nano`" elif [ -x "`which vim`" ]; then EDITOR="`which vim`" elif [ -x "`which vi`" ]; then EDITOR="`which vi`" else echo "No suitable editor found." echo "Please define $EDITOR or configure /etc/alternatives/editor." exit fi fi $EDITOR $1 } do_run_test() { backupninja --test --run $1 echo "Hit return to continue..." read } do_disable() { mv $1 $1.disabled } do_enable() { mv $1 ${1%.*} } do_rename() { dir=`dirname $1` filename=`basename $1` inputBox "rename action" "enter a new filename" $filename mv $dir/$filename $dir/$REPLY } doaction() { action=$1 base=`basename $action` if [ "${base##*.}" == "disabled" ]; then enable="enable"; else enable="disable"; fi while true; do menuBox "action menu" "$action $first" \ main "return to main menu" \ view "view configuration" \ xedit "launch external editor" \ $enable "$enable action" \ name "change the filename" \ run "run this action now" \ test "do a test run" \ kill "remove this action" [ $? = 1 ] && return; result="$REPLY" case "$result" in "view") dialog --textbox $action 0 0;; "xedit") do_xedit $action;; "disable") do_disable $action; return;; "enable") do_enable $action; return;; "name") do_rename $action; return;; "run") do_run $action;; "test") do_run_test $action;; "kill") do_rm_action $action; return;; "main") return;; esac 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 if [ ! -x "`which dialog`" ]; then echo "ninjahelper is a menu based wizard for backupninja." echo "It requires 'dialog' in order to run. Do you want to install dialog now?" while true; do echo -n "(yes/no): " read install if [ "$install" == "yes" ]; then apt-get install dialog break elif [ "$install" == "no" ]; then exit else echo "You must answer 'yes' or 'no'" fi done fi # bootstrap conffile="@CFGDIR@/backupninja.conf" if [ ! -r "$conffile" ]; then echo "Configuration file $conffile not found." exit 1 fi # find $libdirectory libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'` if [ -z "$libdirectory" ]; then if [ -d "@libdir@" ]; then libdirectory="@libdir@" else echo "Could not find entry 'libdirectory' in $conffile." exit 1 fi else if [ ! -d "$libdirectory" ]; then echo "Lib directory $libdirectory not found." exit 1 fi fi # include shared functions . $libdirectory/easydialog . $libdirectory/tools # am I running as root? if [ "$UID" != "0" ]; then 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 $scriptdirectory -follow -name '*.helper'`; do check_perms $file . $file done setApplicationTitle "ninjahelper" setDimension 75 19 ##################################################### ## main event loop while true; do menulist= action= let "i = 1" for file in `find $conf/etc/backup.d/ -type f | sort -n`; do menulist="$menulist $i $file" actions[$i]=$file let "i += 1" done menuBox "main menu" "Select a backup action for more options, or create a new action:" $menulist \ new "create a new backup action" \ quit "leave ninjahelper" [ $? = 1 -o $? = 255 ] && exit 0; choice="$REPLY" if [ "$choice" == "new" ]; then donew; elif [ "$choice" == "quit" ]; then exit 0; else action=${actions[$choice]}; if [ -f "$action" ]; then doaction $action else msgBox "error" "error: cannot find the file '$action'" fi fi done