Releasing new version 0.99.14.
[grml-terminalserver.git] / grml-terminalserver-config
1 #!/bin/bash
2 # Filename:      terminalserver-config
3 # Purpose:       configuration program for grml-terminalserver
4 # Authors:       grml-team (grml.org), (c) Michael Gebetsroither <gebi@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8
9
10 ###
11 ### __INCLUDES
12 ###
13 . /etc/grml/sh-lib
14 #. /etc/grml/sysexits-sh
15
16
17
18 ###
19 ### __VARIABLES
20 ###
21
22 verbose_=0
23
24 # this file holds all variable definitions
25 SHARED_PROG_VARS_="/usr/share/grml-terminalserver/shared_prog_vars"
26 isExistent $SHARED_PROG_VARS_ die
27 . $SHARED_PROG_VARS_
28
29 # variables used in the config file for grml-terminalserver
30 INTERFACE_=""
31 IP_=""
32 NETMASK_=""
33 GW_=""
34 NAMESERVERS_=""
35 IPRANGE_FROM_=""
36 IPRANGE_TO_=""
37 NETWORK_=""
38 OPTIONS_=""
39 BOOT_ARGS_=""
40 NAT_INTERFACE_=""
41
42
43 ###
44 ### __FUNCTIONS
45 ###
46
47 function printUsage
48 {
49   cat <<EOT
50 Usage: "$PROG_NAME__" [OPTIONS] <command>
51
52 $PROG_NAME__ is the config program for the terminalserver coming with grml.
53
54 COMMANDS:
55
56    help             This help text
57    interactive      Interactive Configuration of the grml-terminalserver
58    initrd           Only create the initrd
59    clean            Remove all configfiles created during user configuration
60    <default>        interactive mode
61
62 OPTIONS:
63    -v               verbose (show what is going on, v++)
64    -h               this help text
65
66 EOT
67 }
68
69
70 function writeConfig
71 {
72   local date_=""
73
74   if [ -f $CONF_FILE_ ]; then
75     mv -fb $CONF_FILE_ ${CONF_FILE_}-old
76   fi
77
78   date_=`date`
79   cat <<EOT > $CONF_FILE_
80 # GRML TERMINAL-SERVER CONFIG
81 # created on "$date_"
82 INTERFACE_="$INTERFACE_"
83 IP_="$IP_"
84 NETWORK_="$NETWORK_"
85 NETMASK_="$NETMASK_"
86 GW_="$GW_"
87 NAMESERVERS_="$NAMESERVERS_"
88 IPRANGE_FROM_="$IPRANGE_FROM_"
89 IPRANGE_TO_="$IPRANGE_TO_"
90 OPTIONS_="$OPTIONS_"
91 BOOT_ARGS_="$BOOT_ARGS_"
92 NAT_INTERFACE_="$NAT_INTERFACE_"
93
94 EOT
95   notice "config successfully safed to \"$CONF_FILE_\""
96 }
97
98
99 # AUTOMATIC CONFIGURATION  {{{
100 function checkParamArg
101 {
102   local param_name="$1"
103   local arg="$2"
104
105   #eval "echo $`echo $test`"
106   echo $arg |grep "^[-|+]" &>/dev/null || return
107
108   die "Argument from $param_name looks like another parameter \"$arg\"" 1
109 }
110
111 function actionAutoconf
112 {
113   checkParamArg "-i" "$interface_"
114 }
115 # }}}
116
117 # INITRD {{{
118 function actionMkInitrd
119 {
120   echo "Installing initrd $PATH_/minirt26.gz:"
121   # until we have a stable file location API let's use
122   # an according heuristic
123   initrd_=initrd.img-"$(uname -r)"
124   cp /boot/"$initrd_" "$PATH_"/minirt26.gz || die "Could not copy /boot/$initrd_"
125 }
126
127 # }}}
128
129 # INTERACTIVE CONFIGURATION  {{{
130
131 function actionInteractive
132 {
133   local i=""
134
135   dprint "running in interactive mode"
136
137   local card_title_="Choose network device connected to client network"
138   local card_message_="Available network devices:"
139   local iprange_title_="IP Address range for clients"
140   local iprange_message_="
141 Please enter the desired IP-Range of addresses that should be allocated by clients, separated by a single space.
142
143 Example:
144           192.168.0.101 192.168.0.200
145
146 for addresses from 192.168.0.101 to (and including) 192.168.0.200.
147
148 "
149   local runconfig_title_="Networkcard config"
150   local runconfig_message_="Would you like to configure your interfaces now?"
151
152   # on which interfaces should we listen
153   local netdevices_="$(grep -ve 'lo:' -ve 'Inter-|' -ve 'face |bytes' /proc/net/dev | awk -F: '{print $1}')"
154   local device_list_=""
155   for INTERFACE_ in $netdevices_; do device_list_="$device_list_ ${INTERFACE_} Networkcard_${INTERFACE_##eth}"; done
156     echo -n "" >"$TMP_"
157     $DIALOG_ --backtitle "$BACK_TITLE_" --title "$card_title_" --menu "$card_message_" \
158       0 0 18 $device_list_ 2>"$TMP_" || warn "could not get network-interface"
159   INTERFACE_="$(<$TMP_)" ; echo -n "" >"$TMP_"
160
161   while true; do
162     IP_=`netGetIp "$INTERFACE_" warn`
163     NETMASK_=`netGetNetmask "$INTERFACE_" warn`
164     netValidIp "$IP_" warn && break
165     $DIALOG_ --backtitle "$BACK_TITLE_" --title "$runconfig_title_" --yesno "$runconfig_message_" 18 45 && \
166       netcardconfig || die "Could not get interface" $?
167   done
168
169   IPRANGE_FROM_=`execute "ipcalc -nb $IP_/$NETMASK_" warn |awk '/HostMin/{print $2}'`
170   IPRANGE_TO_=`execute "ipcalc -nb $IP_/$NETMASK_" warn |awk '/HostMax/{print $2}'`
171   NETWORK_=`execute "ipcalc -nb $IP_/$NETMASK_" warn |awk '/Network:/{print $2}'`
172   NETWORK_=${NETWORK_%/*}
173   local iprange_=""
174   while [ -z "$IPRANGE_FROM_" -o -z "$IPRANGE_TO_" -o -z "$iprange_" ]; do
175     iprange_="$IPRANGE_FROM_ $IPRANGE_TO_"
176     echo -n "" >"$TMP_"
177     $DIALOG_ --clear --backtitle "$BACK_TITLE_" --title "$iprange_title_ ($INTERFACE_=$IP_/$NETMASK_)" \
178       --inputbox "$iprange_message_" 18 75 "$iprange_" 2>"$TMP_" || die "problems getting network range" $?
179
180     iprange_="$(<$TMP_)"
181     IPRANGE_FROM_="${iprange_%% *}"
182     IPRANGE_TO_="${iprange_##* }"
183
184     for i in "$IPRANGE_FROM_" "$IPRANGE_TO_"; do
185       netValidIp "$i" warn || iprange_=""
186     done
187   done
188
189   NAMESERVERS_=`netGetNameservers warn`
190   GW_=`netGetDefaultGateway warn`
191   GW_DEV_=`/sbin/ip route get "$GW_" | awk '{ print $3; exit; }'`
192   if [ "$GW_DEV_" != "$INTERFACE_" ] && [ "$GW_DEV_" != "" ]; then
193     # GW_DEV_ of server is not the same device as the one serviced by dhcpd
194     # so it doesn't make sense to provide the GW_ address to the clients
195     local do_nat_="YES"
196     local do_nat_title_="Network Address Translation"
197     local do_nat_message_="
198 Do you want to set up NAT so that clients booting from this
199 grml-terminalserver can use this machine also as gateway to
200 the internet?"
201
202     $DIALOG_ --clear --backtitle "$BACK_TITLE_" --title "$do_nat_title_" --yesno "$do_nat_message_" 15 75 || \
203       do_nat_="NO"
204     if [ "$do_nat_" = "YES" ]; then
205       # user wants NAT, we give the clients the server address as
206       # gateway as well
207       GW_="$IP_"
208       NAT_INTERFACE_="$GW_DEV_"
209     else
210       # no NAT, no sensible gateway
211       GW_=""
212       NAT_INTERFACE_=""
213     fi
214   fi
215
216   # get options
217   #local OPT_IPTABLES_="yes"
218   #local OPT_SSH_="yes"
219   #local OPT_DISTCC_="yes"
220   #local OPT_SQUID_=""
221
222   local OPTIONS_TITLE_="Options"
223   local OPTIONS_MESSAGE_="Please give the appropriate options you want the clients to use:
224
225 grml2hd   - Make a non-interactive remote installation
226
227
228
229 "
230 #  local OPTIONS_MESSAGE_="Please give the appropriate options you want the clients to use:
231 #
232 #iptables  - Only the server should be able to access the clients
233 #ssh       - A ssh-key will be created on the server and distributed to the clients
234 #distcc    - You want to use the clients as compile-farm (ssh options recommned)
235 #
236 #"
237
238   local OPT_IPTABLES_DESC_="Start iptables on the clients"
239   local OPT_SSH_DESC_="Start ssh on the clients"
240   local OPT_DISTCC_DESC_="Start distcc on the clients"
241   local OPT_GRML2HD_DESC_="Remote install grml on the network clients"
242   # dialog options (enable if implemented)
243   #iptables "$OPT_IPTABLES_DESC_" off \
244   #ssh "$OPT_SSH_DESC_" off \
245   #distcc "$OPT_DISTCC_DESC_" off \
246   echo -n "" >"$TMP_"
247   $DIALOG_ --clear --separate-output --backtitle "$BACK_TITLE_" --title "$OPTIONS_TITLE_" --checklist "$OPTIONS_MESSAGE_" 25 80 10 \
248   grml2hd "$OPT_GRML2HD_DESC_" off \
249     2>$TMP_ || die "could not get terminalserver options" $?
250   while read tmp_option_; do
251     OPTIONS_="$OPTIONS_ $tmp_option_"
252   done <$TMP_
253
254   # parse options
255   for i in $OPTIONS_; do
256     case "$i" in
257       grml2hd)  optGrml2Hd || return 1 ;;
258     esac
259   done
260
261   echo -n "" >"$TMP_"
262   local OPTIONS_BOOTARG_MESSAGE_="Here you can add additional boot arguments for the clients seperated by spaces:
263
264 Quite usefull examples:
265
266 ssh=<pw>              - Start ssh server and set password of user grml to pw
267 services=<1,2,3>      - Execute /etc/init.d/{1,2,3} start
268 console=ttyS0,9600n8  - Initialise serial console
269 startx                - Boot into X
270
271
272 "
273   $DIALOG_ --clear --no-collapse --backtitle "$BACK_TITLE_" --title "$OPTIONS_TITLE_" --inputbox "$OPTIONS_BOOTARG_MESSAGE_" 0 0\
274     2>$TMP_ || die "problems getting additional boot arguments"
275   BOOT_ARGS_="$BOOT_ARGS_ $(<$TMP_)"
276
277   writeConfig
278   actionMkInitrd
279   notice "GRML terminalserver successfully configured"
280 }
281 # }}}
282
283 # OPTIONS GETTING DIALOG {{{
284 function optGrml2Hd
285 {
286   local GRML2HD_TITLE_='Grml2hd options dialog'
287   local tmp_=''
288   local options_='BOOT_IMAGE=grml2hd'
289
290   # get partition to install grml2hd on
291   OPTIONS_PARTITION_MSG_='Please specify the target partition where to install grml'
292   PARTITION_TITLE_='Partition selection'
293   echo -n "" >"$TMP_"
294   $DIALOG_ --clear --backtitle "$BACK_TITLE_" --title "$PARTITION_TITLE_" --inputbox \
295     "$OPTIONS_PARTITION_MSG_" 0 75 '/dev/hda1' 2>$TMP_ || die "problems getting partition"
296   tmp_="partition=$(<$TMP_)"
297   options_="$options_ $tmp_"
298
299   # get filesystem type
300   OPTION_FS_TYPE_='Please specify the filesystem type'
301   FS_TITLE_='Filesystem selection'
302   echo -n "" >"$TMP_"
303   $DIALOG_ --clear --backtitle "$BACK_TITLE_" --title "$FS_TITLE_" --inputbox \
304   "$OPTION_FS_TYPE_" 0 75 'ext3' 2>$TMP_ || die "problems getting filesystem type"
305   tmp_="filesystem=$(<$TMP_)"
306   options_="$options_ $tmp_"
307
308   # get where to save mbr
309   OPTION_MBR_='Please specify the location where to save the mbr'
310   MBR_TITLE_='Select location of mbr'
311   echo -n "" >"$TMP_"
312   $DIALOG_ --clear --backtitle "$BACK_TITLE_" --title "$MBR_TITLE_" --inputbox \
313     "$OPTION_MBR_" 0 75 '/dev/hda' 2>$TMP_ || die "problems getting location where to write mbr"
314   tmp_="mbr=$(<$TMP_)"
315   options_="$options_ $tmp_"
316
317   # get first user
318   OPTION_USER_='Who should be the first user on the system'
319   USER_TITLE_='User selection'
320   echo -n "" >"$TMP_"
321   $DIALOG_ --clear --backtitle "$BACK_TITLE_" --title "$USER_TITLE_" --inputbox \
322     "$OPTION_USER_" 0 75 'grml' 2>$TMP_ || die "problems getting first user of system"
323   tmp_="user=$(<$TMP_)"
324   options_="$options_ $tmp_"
325
326   BOOT_ARGS_="$options_"
327 }
328 #}}}
329
330
331 function removeTmpFiles
332 {
333   execute "rm -f $TMP_" warn
334 }
335
336 function actionClean
337 {
338   for i in dhcpd.conf minirt26.gz; do
339     execute "rm -f $PATH_/$i*"
340   done
341
342   for i in $CARDS_DETECTED_BY_DISCOVER $CONF_FILE_; do
343     execute "rm -f $i"
344   done
345
346 }
347
348
349 ###
350 ### __MAIN
351 ###
352
353 while getopts "i:hv" opt; do
354   case "$opt" in
355     i) interface_=$OPTARG ;;
356     h) printUsage; exit ;;
357     v) let verbose_=$verbose_+1 ;;
358     ?) printUsage; exit 64 ;;
359   esac
360 done
361 shift $(($OPTIND - 1))  # set ARGV to the first not parsed commandline parameter
362 setVerbose $verbose_
363
364 case "$1" in
365   help)   printUsage; exit 0 ;;
366 esac
367
368 checkRoot die 'You have to be root to use this program'
369 disableSyslog
370
371 execute "mkdir -p $PATH_" die
372
373 TMP_=`mktemp -t grml-terminalserver-config.XXXXXX` || die "Could not create tmpfile" $?
374 setExitFunction 'removeTmpFiles'
375
376
377 . $DEFAULT_CONFIG_
378 . $CONFIG_
379 # used config vars:
380 # MODULES_PATH_
381 # MODULES_PATH_ROOT_DIFF_
382 # KERNEL_VERSION_
383 # ORIGINAL_INITRD_
384 if [[ $MODULES_PATH_ == "" || $KERNEL_VERSION_ == "" || $ORIGINAL_INITRD_ == "" ]]; then
385   warn "MODULES_PATH_=\"$MODULES_PATH_\" \
386 KERNEL_VERSION_=\"$KERNEL_VERSION_\" \
387 ORIGINAL_INITRD_=\"$ORIGINAL_INITRD_\""
388   die "False configuration, please update $CONFIG_"
389 fi
390
391
392 case "$1" in
393   interactive)  actionInteractive ;;
394   initrd) actionMkInitrd ;;
395   clean)  actionClean ;;
396   *)    actionInteractive ;;
397 esac
398
399 removeTmpFiles
400 # END OF FILE
401 ################################################################################
402 # vim:foldmethod=marker tabstop=2 expandtab shiftwidth=2