r3563@krups: intrigeri | 2005-11-16 20:32:41 +0100
[matthijs/upstream/backupninja.git] / src / ninjahelper.in
1 #!@BASH@
2
3 ####################################################
4 ## Functions
5
6 function check_perms() {
7         local file=$1
8         local perms=`ls -ld $file`
9         group_w_perm=${perms:5:1}
10         world_w_perm=${perms:8:1}
11         if [ "$group_w_perm" == "w" -o "$world_w_perm" == "w" ]; then
12             echo $perms
13             echo "helper scripts must not be group or world writable! Dying on file $file"
14             exit
15         fi
16         if [ `ls -ld $file | awk '{print $3}'` != "root" ]; then
17                 echo "helper scripts must be owned by root! Dying on file $file"
18                 exit
19         fi
20 }
21
22
23 ##
24 ## returns the next available file name given a file
25 ## in the form @CFGDIR@/backup.d/10.sys
26 ## sets variable $next_filename
27 ##
28 get_next_filename() {
29   next_filename=$1
30   dir=`dirname $next_filename`
31   file=`basename $next_filename`
32   number=${file:0:2}
33   suffix=${file:3}
34   while [ -f $next_filename ]; do
35     let "number += 1"
36     next_filename="$dir/$number.$suffix"
37   done
38 }
39
40 ##
41 ## installs packages (passed in as $@) if not present
42 ##
43 require_packages() {
44        for pkg in "$@"; do
45            installed=`dpkg -s $pkg | grep 'ok installed'`
46        if [ -z "$installed" ]; then 
47            booleanBox "install $pkg?" "This backup action requires package $pkg. Do you want to install it now?"
48            if [ $? = 0 ]; then
49               apt-get install $pkg
50               echo "hit return to continue...."
51               read
52            fi
53        fi
54     done
55 }
56
57 ##
58 ## menu for the wizards
59 ##
60 donew() {
61   # reset some variables
62   unset host_or_vservers
63   unset vservers_chooser_vsnames
64   # menu
65   listBegin "new action menu" "select an action to create"
66   listItem return "return to main menu"
67   for data in $HELPERS; do
68     data=${data//_/ }
69     helper_function=${data%%:*}
70     helper_info=${data##*:}
71     listItem $helper_function "$helper_info"
72   done
73   listDisplay menu
74     
75   [ $? = 1 ] && return
76   result="$REPLY"
77   [ "$result" = "return" ] && return
78   result=${result}_wizard
79   $result
80 }
81
82 do_rm_action() {
83    booleanBox "remove action" "Are you sure you want to remove action file $1?"
84    if [ $? = 0 ]; then
85      rm $1;
86    fi
87 }
88
89 do_run() {
90    backupninja --run $1
91    echo "Hit return to continue..."
92    read
93 }
94
95 do_xedit() {
96    if [ -z "$EDITOR" -o ! -x "`which $EDITOR`" ]; then
97       if [ -h /etc/alternatives/editor -a -x "`readlink /etc/alternatives/editor`" ]; then
98          EDITOR="`readlink /etc/alternatives/editor`"
99       elif [ -x "`which nano`" ]; then
100          EDITOR="`which nano`"
101       elif [ -x "`which vim`" ]; then
102          EDITOR="`which vim`"
103       elif [ -x "`which vi`" ]; then
104          EDITOR="`which vi`"
105       else
106          echo "No suitable editor found."
107          echo "Please define $EDITOR or configure /etc/alternatives/editor."
108          exit
109       fi
110    fi
111    $EDITOR $1
112 }
113
114 do_run_test() {
115   backupninja --test --run $1
116   echo "Hit return to continue..."
117   read
118 }
119
120 do_disable() {
121   mv $1 $1.disabled
122 }
123
124 do_enable() {
125   mv $1 ${1%.*}
126 }
127
128 do_rename() {
129   dir=`dirname $1`
130   filename=`basename $1`
131   inputBox "rename action" "enter a new filename" $filename
132   mv $dir/$filename $dir/$REPLY
133 }
134
135 doaction() {
136   action=$1
137   base=`basename $action`
138   if [ "${base##*.}" == "disabled" ]; then
139      enable="enable";
140   else
141      enable="disable";
142   fi
143   while true; do
144     menuBox "action menu" "$action $first" \
145       main "return to main menu" \
146       view "view configuration" \
147       xedit "launch external editor" \
148       $enable "$enable action" \
149       name "change the filename" \
150       run "run this action now" \
151       test "do a test run" \
152       kill "remove this action" 
153     [ $? = 1 ] && return;
154     result="$REPLY"
155         case "$result" in
156            "view") dialog --textbox $action 0 0;; 
157            "xedit") do_xedit $action;;
158            "disable") do_disable $action; return;;
159            "enable") do_enable $action; return;;
160            "name") do_rename $action; return;;
161            "run") do_run $action;;
162            "test") do_run_test $action;; 
163            "kill") do_rm_action $action; return;;
164            "main") return;;
165         esac
166   done
167 }
168
169 #####################################################
170 ## VSERVERS RELATED FUNCTIONS
171
172 ##
173 ## If vservers are not enabled, exit silently and set host_or_vservers to 'host'.
174 ## Else, have the user choose the target he/she wants to perform the backup on:
175 ##   - host system only
176 ##   - some vservers only
177 ##   - both the host system and some vservers
178 ## Sets, respectively, $host_or_vservers to 'host', 'vservers', or 'both'
179 ## $host_or_vservers is unset when a new helper is run.
180 ## Returns 1 if cancelled.
181 ##
182 host_or_vservers_chooser() {
183    local title=$1
184    # exit silently if vservers are not enabled
185    if [ "$vservers" != "yes" ]; then
186       host_or_vservers='host'
187       return
188    fi
189    # if there is one, set the previously chosen item as the default
190    [ -n "$host_or_vservers" ] && setDefault $host_or_vservers
191    menuBox "$title - src" "Do you want to operate on the host system and/or on vservers?" \
192       "host" "Host system only" \
193       "vservers" "Vservers only" \
194       "both" "Host system and Vservers"
195    [ $? = 0 ] || return 1
196    case $REPLY in
197       "host")
198          host_or_vservers='host'
199          ;;
200       "vservers")
201          host_or_vservers='vservers'
202          ;;
203       "both")
204          host_or_vservers='both'
205          ;;
206    esac
207 }
208
209 ##
210 ## If the argument is the name of a vserver selected for backup (in
211 ## $vservers_chooser_vsnames), echoes 'on' and returns 0.
212 ## Else, echoes 'off' and returns 1.
213 ##
214 vserver_is_selected() {
215    local vserver=$1
216    local vserver_is_selected=1
217    local i
218    for i in $vservers_chooser_vsnames ; do
219       [ "$vserver" == "$i" ] && vserver_is_selected=0
220    done
221    if [ $vserver_is_selected = 0 ]; then
222       echo on
223    else
224       echo off
225    fi
226    return $vserver_is_selected
227 }
228
229 ##
230 ## Have the user choose among "all vservers" and a not-empty subset of these.
231 ## Sets global $vservers_chooser_vsnames variable to "all" or to a
232 ## space-separated name list.
233 ## Depends on host_or_vservers() to have already run.
234 ## $vservers_chooser_vsnames is unset when a new helper is run.
235 ## Returns 1 if cancelled.
236 ##
237 vservers_chooser() {
238    local title=$1
239    local i=
240    [ -n "$VROOTDIR" ] || (msgBox "warning" "VROOTDIR is not set in $conffile and could not be guessed."; return 1)
241    [ -d "$VROOTDIR" ] || (msgBox "warning" "VROOTDIR ($VROOTDIR) does not exist."; return 1)
242
243    booleanBox "$title" "Do you want to backup all vservers?" ` [ -z "$vservers_chooser_vsnames" -o "$vservers_chooser_vsnames" == "all" ] || echo no`
244    if [ $? = 0 ]; then
245       vservers_chooser_vsnames="all"
246    else
247       # choose among the existing vservers
248       local vserver=
249       local vserver_was_selected=
250       REPLY=
251       while [ -z "$REPLY" ]; do
252          listBegin "$title" "Choose at least one Linux-Vserver to backup:"
253             # list existing vservers, preselecting the previously selected ones
254             for vserver in `ls $VROOTDIR | grep -E -v "lost+found|ARCHIVES"`; do
255                listItem "$vserver" "Backup $vserver vserver" `vserver_is_selected $vserver`
256             done
257          listDisplay checklist
258          [ $? = 0 ] || return 1
259       done
260       # remove quotes around each vserver name
261       vservers_chooser_vsnames=`echo $REPLY | tr -d '"'`
262    fi
263 }
264
265 #####################################################
266 ## begin program
267
268 if [ ! -x "`which dialog`" ]; then
269         echo "ninjahelper is a menu based wizard for backupninja."
270         echo "It requires 'dialog' in order to run. Do you want to install dialog now?"
271         while true; do
272           echo -n "(yes/no): "
273           read install
274           if [ "$install" == "yes" ]; then
275              apt-get install dialog
276              break
277           elif [ "$install" == "no" ]; then
278              exit
279           else
280              echo "You must answer 'yes' or 'no'"
281           fi
282     done
283 fi
284
285 # bootstrap
286 conffile="@CFGDIR@/backupninja.conf"
287 if [ ! -r "$conffile" ]; then
288         echo "Configuration file $conffile not found." 
289         exit 1
290 fi
291
292 # find $libdirectory
293 libdirectory=`grep '^libdirectory' $conffile | awk '{print $3}'`
294 if [ -z "$libdirectory" ]; then
295         if [ -d "@libdir@" ]; then
296            libdirectory="@libdir@"
297         else
298            echo "Could not find entry 'libdirectory' in $conffile." 
299            exit 1
300         fi
301 else
302         if [ ! -d "$libdirectory" ]; then
303            echo "Lib directory $libdirectory not found." 
304            exit 1
305         fi
306 fi
307
308 # include shared functions
309 . $libdirectory/easydialog
310 . $libdirectory/tools
311
312 # am I running as root?
313 if [ "$UID" != "0" ]; then
314         msgBox "warning" "$0 must be run by root!"
315         exit 1
316 fi
317
318 # get global config options (second param is the default)
319 setfile $conffile
320 getconf configdirectory @CFGDIR@/backup.d
321 getconf scriptdirectory @datadir@
322 getconf vservers no
323 getconf VSERVERINFO /usr/sbin/vserver-info
324 getconf VSERVER /usr/sbin/vserver
325 getconf VROOTDIR `if [ -f "$VSERVERINFO" ]; then $VSERVERINFO info SYSINFO |grep vserver-Rootdir | awk '{print $2}'; fi`
326
327 # load all the helpers
328 HELPERS=""
329 for file in `find $scriptdirectory -follow -name '*.helper'`; do
330    check_perms $file
331    . $file
332 done
333
334 setApplicationTitle "ninjahelper"
335 setDimension 75 19
336
337 #####################################################
338 ## main event loop
339
340 while true; do
341
342 menulist=
343 action=
344 let "i = 1"
345 for file in `find $conf/etc/backup.d/ -type f | sort -n`; do
346   menulist="$menulist $i $file"
347   actions[$i]=$file
348   let "i += 1"
349 done
350
351 menuBox "main menu" "Select a backup action for more options, or create a new action:" $menulist \
352   new "create a new backup action" \
353   quit "leave ninjahelper" 
354
355 [ $? = 1 -o $? = 255 ] && exit 0;
356
357 choice="$REPLY"
358 if [ "$choice" == "new" ]; then
359   donew;
360 elif [ "$choice" == "quit" ]; then
361   exit 0;
362 else
363   action=${actions[$choice]};
364   if [ -f "$action" ]; then
365      doaction $action
366   else
367      msgBox "error" "error: cannot find the file '$action'"
368   fi
369 fi
370
371
372 done