- moved here from sysv/
[util-vserver.git] / linuxconf / newvserver.subst
1 #!/usr/bin/shellmod
2 # This module is used to create a new virtual private server
3
4 # This module may be use inside linuxconf
5 # Do linuxconf --modulemain shellmod --setmod @SBINDIR@/newvserver
6
7 # Load shellmod support function
8 . /usr/lib/linuxconf/lib/shellmod-lib.sh
9
10 USR_SBIN=@SBINDIR@
11 USR_LIB_VSERVER=@PKGLIBDIR@
12 VSERVER_CMD=$USR_SBIN/vserver
13 CHBIND_CMD=$USR_SBIN/chbind
14 CHCONTEXT_CMD=$USR_SBIN/chcontext
15 SAVE_S_CONTEXT_CMD=$USR_LIB_VSERVER/save_s_context
16 CAPCHROOT_CMD=$USR_LIB_VSERVER/capchroot
17 VSERVERKILLALL_CMD=$USR_LIB_VSERVER/vserverkillall
18
19
20 usage(){
21         cat <<-EOF >&2
22
23 newvserver [ options ]
24
25     Interactive utility to create vservers.
26
27 Options:
28     --name: Set the name of the new vserver.
29     --desc: Set the description.
30     --unify 1/0: Turn on unification on and off.
31     --hostname: Set the host name of the new vserver
32     --ip: Set the IP number(s)
33     --ondev: Install the IP numbers as IP aliases on device.
34     --clone: Create the vserver from another one or a distribution CD.
35
36 The distribution CD are identified by special strings:
37     #rh9.0m: RedHat 9 minimal
38     #rh9.0f: RedHat 9 complete first CD
39     #rh8.0m: RedHat 8 minimal
40     #rh8.0f: RedHat 8 complete first CD
41     #rh7.3m: RedHat 7.3 minimal
42     #rh7.3f: RedHat 7.3 complete first CD
43     #rh7.2m: RedHat 7.2 minimal
44     #rh7.2f: RedHat 7.2 complete first CD
45
46 EOF
47 }
48
49 register(){
50         qecho regmenu main MENU_MISCSERV "Create a new vserver"
51 }
52
53 check_name(){
54         LEN=`echo -n $1 | wc -c`
55         SMALL=`expr $LEN \<= 10`
56         if [ "$SMALL" = "1" ] ; then
57                 return 0
58         fi
59         return 1
60 }
61
62 check_hostname(){
63         case $1 in
64         *\.*)
65                 return 0
66                 ;;
67         *)
68                 ;;
69         esac
70         return 1
71 }
72
73 check_ip(){
74         case $1 in
75         *\.*\.*\.*)
76                 return 0
77                 ;;
78         *)
79                 ;;
80         esac
81         return 1
82 }
83
84 check_device(){
85         if [ "$1" = "" ] ; then
86                 return 1;
87         fi
88         return 0
89 }
90
91 # Tell the user to mount the CD
92 check_cd(){
93         echo defval s1 "Make sure the $1"
94         echo defval s1 "is mounted on /mnt/cdrom"
95         echo defval s1
96         echo defval s1 "Execute \"mount /mnt/cdrom\" if not"
97         echo notice =s1
98 }
99
100 # Set a fake fstab and mtab in a vserver
101 # $1 is the vserver path (/vserver/id)
102 set_fstab(){
103         mkdir -p $1/etc
104         echo /dev/hdv1  /       ext2    defaults        1       1 >$1/etc/fstab
105         echo /dev/hdv1  /       ext2    rw      1       1 >$1/etc/mtab
106 }
107
108 # Show a progress bar during installation
109 # The sub-process sends the number of output line first, then the lines
110 execprogress(){
111         LOG=$1
112         title=$2
113         desc=$3
114         shift; shift; shift
115         $* |
116         (
117                 >$LOG
118                 read SIZE rest
119                 qecho DIALOG
120                 qecho settype DIATYPE_POPUP
121                 qecho newf_str p1 "Package"
122                 qecho newf_gauge s1 "$desc" 0 $SIZE
123                 qecho show "$title" "$SIZE $rest"
124                 nb=0
125                 while read pkg line
126                 do
127                         nb=`expr $nb + 1`
128                         printf "%-20s %s\n" $pkg $line >>$LOG
129                         qecho newf_str p1 "Package" "$pkg"
130                         qecho newf_gauge s1 "$desc" $nb $SIZE
131                         qecho show "$title" "$SIZE $rest"
132                 done
133                 qecho end
134         )
135 }
136
137 # install some packages with a progress bar
138 installpkgs(){
139         LOG=$1
140         shift
141         execprogress $LOG "Installing" "Packages installed" $*
142 }
143
144 # Point d'entrĂ© du module
145 main(){
146         name=
147         desc=
148         clone=/
149         unify=1
150         hostname=
151         ip=
152         ondev=eth0
153         if [ -f /etc/vservers/newvserver.defaults ] ; then
154                 source /etc/vservers/newvserver.defaults
155         fi
156         while [ "$1" != "" ]
157         do
158                 case $1 in
159                 --help)
160                         usage
161                         exit
162                         ;;
163                 --name)
164                         name=$2
165                         shift; shift
166                         ;;
167                 --desc)
168                         desc=$2
169                         shift; shift
170                         ;;
171                 --unify)
172                         unify=$2
173                         shift; shift
174                         ;;
175                 --hostname)
176                         hostname=$2
177                         shift; shift
178                         ;;
179                 --ip)
180                         ip="$2"
181                         shift; shift
182                         ;;
183                 --ondev)
184                         ondev=$2
185                         shift; shift
186                         ;;
187                 --clone)
188                         clone=$2
189                         shift; shift
190                         ;;
191                 *)
192                         qecho error "Invalid option $1"
193                         exit 1
194                 esac
195         done
196         qecho DIALOG
197         qecho newf_title top 1 top
198         qecho newf_str name "Vserver name (max 10 chars)" $name
199         qecho newf_str desc "Vserver description" "$desc"
200         qecho newf_list clone "Clone vserver" $clone
201         for conf in /etc/vservers/*.conf
202         do
203                 case $conf in
204                 /etc/vservers/\*.conf)
205                         ;;
206                 *)
207                         DESC=`grep "# Description:" $conf | ( read a b c; echo $c)`
208                         qecho listitem `basename $conf .conf` "$DESC"
209                         ;;
210                 esac
211         done
212         qecho listitem / "Root server"
213         qecho listitem "#rh9.0m" "From RedHat 9.0 CDrom/Minimal"
214         qecho listitem "#rh9.0f" "From RedHat 9.0 CDrom/Full"
215         qecho listitem "#rh8.0m" "From RedHat 8.0 CDrom/Minimal"
216         qecho listitem "#rh8.0f" "From RedHat 8.0 CDrom/Full"
217         qecho listitem "#rh7.3m" "From RedHat 7.3 CDrom/Minimal"
218         qecho listitem "#rh7.3f" "From RedHat 7.3 CDrom/Full"
219         qecho listitem "#rh7.2" "From RedHat 7.2 CDrom"
220         #qecho listitem "#mdk8.2m" "From Mandrake 8.2 CDrom/Minimal"
221         #qecho listitem "#mdk8.2f" "From Mandrake 8.2 CDrom/Full"
222         qecho newf_chk unify "Unified mode" 1 "Share disk space" $unify
223
224         qecho newf_title Networking 1 Networking
225         qecho newf_str hostname "Host name" $hostname
226         qecho newf_info "" "Up to 16 IP numbers"
227         qecho newf_str ip "IP number(s)" "$ip"
228         qecho newf_str ondev "Install IP on device" $ondev
229
230         qecho newf_title Authentication 1 Authentication
231         qecho newf_pass pass1 "Root password"
232         qecho newf_pass pass2 "Root password (retype)"
233         qecho newf_chk usemd5 "Password format" 1 "Use MD5"
234         qecho newf_chk useshadow "Password location" 1 "/etc/shadow"
235
236         qecho newf_title NIS/LDAP 1 NIS/LDAP
237         qecho newf_str nisserver  "NIS server"
238         qecho newf_str domainname "NIS domainname"
239         qecho newf_str ldapserver "LDAP server"
240         qecho newf_str ldapbasedn "LDAP base dn"
241
242         qecho newf_title Services 1 Services
243         qecho newf_chk crond  "crond"  1 "Scheduled tasks"
244         qecho newf_chk httpd  "httpd"  0 "Web server"
245         qecho newf_chk sshd   "sshd"   1 "Secure shell server"
246         qecho newf_chk cleansshd ""    1 "Redo sshd server keys"
247         qecho newf_chk syslog "syslog" 1 "Message logger"
248         qecho newf_chk xinetd "xinetd" 0 "On demand inet service"
249         qecho newf_chk nscd   "nscd"   0 "Name service cache daemon"
250
251         qecho newf_title "Backup profile" 1 "Backup profile"
252         qecho newf_str bkhostname "Host name"
253         qecho newf_info "" "Up to 16 IP numbers"
254         qecho newf_str bkip "IP number(s)"
255         qecho newf_str bkondev "Install IP on device" eth0
256
257         qecho newf_title Extra 1 Extra
258         qecho newf_chk onboot "Start server" 0 "at boot time"
259         qecho newf_str priority "Start priority" 100
260         qecho newf_str nice "Nice level"
261         qecho newf_info "Available flags" "lock nproc sched hideinfo private"
262         qecho newf_str flags "Flags" "lock nproc"
263         qecho newf_str ulimit "Vserver ulimit" "-H -u 1000"
264
265
266         qecho newf_title "Shared directories" 1 "Shared directories"
267         qecho newf_str dir1 "Directory"
268         qecho newf_str dir2 "Directory"
269         qecho newf_str dir3 "Directory"
270         qecho newf_str dir4 "Directory"
271
272         qecho newf_title "Excluded directories" 1 "Excluded directories"
273         qecho newf_info "" "Won't copy files in those directories"
274         qecho newf_str exdir1 "Directory" "/var/log"
275         qecho newf_str exdir2 "Directory" "/var/run"
276         qecho newf_str exdir3 "Directory" "/var/spool/mail"
277         qecho newf_str exdir4 "Directory" "/tmp"
278         qecho newf_str exdir5 "Directory" ""
279         qecho newf_str exdir6 "Directory" ""
280
281
282         while true
283         do
284                 qecho edit "Vserver basic setup" 
285                 dispatch
286                 if [ $CODE != "accept" ] ; then
287                         break
288                 elif ! check_name $name ; then
289                         qecho error "You must provide a name (10 chars max)"
290                 elif ! check_hostname $hostname ; then
291                         qecho error "You must provide a valid/fully qualified host name"
292                 elif ! check_ip $ip ; then
293                         qecho error "You must provide a valid IP number"
294                 elif ! check_device $ondev ; then
295                         qecho error "You must provide a valid network device"
296                 elif [ "$pass1" != "" -a "$pass1" != "$pass2" ] ; then
297                         echo defval s1 The two passwords differ.
298                         echo defval s1 You must re-enter the root password.
299                         echo error =s1
300                 else
301                         STARTTIME=`date +%s`
302                         ONBOOT=no
303                         if [ "$onboot" = "1" ] ; then
304                                 ONBOOT=yes
305                         fi
306                         VROOT=/vservers/$name
307                         CONF=/etc/vservers/$name.conf
308                         $USR_LIB_VSERVER/install-pre.sh $name
309                         rm -f $CONF >/dev/null 2>/dev/null
310                         echo "# Description: $desc" >>$CONF
311                         echo >>$CONF
312                         echo "if [ \"$PROFILE\" = \"\" ]; then" >>$CONF
313                         echo "  PROFILE=prod" >>$CONF
314                         echo "fi" >>$CONF
315                         echo "case \$PROFILE in" >>$CONF
316                         echo "prod)" >>$CONF
317                         echo "  # Select the IP number(s) assigned to the virtual server" >>$CONF
318                         echo "  # These IPs will be defined as IP alias" >>$CONF
319                         echo "  # The alias will be setup on IPROOTDEV" >>$CONF
320                         echo "  # You can specify the device if needed" >>$CONF
321                         echo "  # IPROOT=\"eth0:1.2.3.4 eth1:3.4.5.6\" " >>$CONF
322                         echo "  IPROOT=\"$ip\"" >>$CONF
323                         echo "  # You can define on which device the IP alias will be done" >>$CONF
324                         echo "  # The IP alias will be set when the server is started and unset" >>$CONF
325                         echo "  # when the server is stopped" >>$CONF
326                         echo "  # The netmask and broadcast are computed by default from IPROOTDEV" >>$CONF
327                         echo "  #IPROOTMASK=" >>$CONF
328                         echo "  #IPROOTBCAST=" >>$CONF
329                         echo "  IPROOTDEV=$ondev" >>$CONF
330                         echo "  # You can set a different host name for the vserver" >>$CONF
331                         echo "  # If empty, the host name of the main server is used" >>$CONF
332                         echo "  S_HOSTNAME=$hostname" >>$CONF
333                         echo "  ;;" >>$CONF
334                         echo "backup)" >>$CONF
335                         echo "  IPROOT=\"$bkip\"" >>$CONF
336                         echo "  #IPROOTMASK=" >>$CONF
337                         echo "  #IPROOTBCAST=" >>$CONF
338                         echo "  IPROOTDEV=$bkondev" >>$CONF
339                         echo "  S_HOSTNAME=$bkhostname" >>$CONF
340                         echo "  ;;" >>$CONF
341                         echo "esac" >>$CONF
342                         echo "# Set ONBOOT to yes or no if you want to enable this" >>$CONF
343                         echo "# virtual server at boot time" >>$CONF
344                         echo "ONBOOT=$ONBOOT" >>$CONF
345                         echo "# Control the start order of the vservers" >>$CONF
346                         echo "# Lower value start first" >>$CONF
347                         echo "PRIORITY=$priority" >>$CONF
348                         echo "# You can set a different NIS domain for the vserver" >>$CONF
349                         echo "# If empty, the current on is kept" >>$CONF
350                         echo "# Set it to \"none\" to have no NIS domain set" >>$CONF
351                         echo "S_DOMAINNAME=$domainname" >>$CONF
352                         echo "# You can set the priority level (nice) of all process in the vserver" >>$CONF
353                         echo "# Even root won't be able to raise it" >>$CONF
354                         echo "S_NICE=$nice" >>$CONF
355                         echo "# You can set various flags for the new security context" >>$CONF
356                         echo "# lock: Prevent the vserver from setting new security context" >>$CONF
357                         echo "# sched: Merge scheduler priority of all processes in the vserver" >>$CONF
358                         echo "#        so that it acts a like a single one." >>$CONF
359                         echo "# nproc: Limit the number of processes in the vserver according to ulimit" >>$CONF
360                         echo "#        (instead of a per user limit, this becomes a per vserver limit)" >>$CONF
361                         echo "# private: No other process can join this security context. Even root" >>$CONF
362                         echo "# Do not forget the quotes around the flags" >>$CONF
363                         echo "S_FLAGS=\"$flags\"" >>$CONF
364                         echo "# You can set various ulimit flags and they will be inherited by the" >>$CONF
365                         echo "# vserver. You enter here various command line argument of ulimit" >>$CONF
366                         echo "# ULIMIT=\"-H -u 200\"" >>$CONF
367                         echo "# The example above, combined with the nproc S_FLAGS will limit the" >>$CONF
368                         echo "# vserver to a maximum of 200 processes" >>$CONF
369                         echo "ULIMIT=\"$ulimit\"" >>$CONF
370                         echo "# You can set various capabilities. By default, the vserver are run" >>$CONF
371                         echo "# with a limited set, so you can let root run in a vserver and not" >>$CONF
372                         echo "# worry about it. He can\'t take over the machine. In some cases" >>$CONF
373                         echo "# you can to give a little more capabilities \(such as CAP_NET_RAW\)" >>$CONF
374                         echo "# S_CAPS=\"CAP_NET_RAW\"" >>$CONF
375                         echo "S_CAPS=\"\"" >>$CONF
376                         echo "# Select an unused context (this is optional)" >>$CONF
377                         echo "# The default is to allocate a free context on the fly" >>$CONF
378                         echo "# In general you don't need to force a context" >>$CONF
379                         echo "#S_CONTEXT=" >>$CONF
380
381                         # Now we create the optional companion startup script
382                         # for the vserver
383                         SCRIPT=/etc/vservers/$name.sh
384                         echo "#!/bin/sh" >$SCRIPT
385                         echo 'case $1 in' >>$SCRIPT
386                         echo "pre-start)" >>$SCRIPT
387                         for dir in $dir1 $dir2 $dir3 $dir4  none
388                         do
389                                 if [ "$dir" != "none" ] ; then
390                                         echo "  mkdir -p $VROOT/$dir" >>$SCRIPT
391                                         echo "  mount --bind $dir $VROOT/$dir" >>$SCRIPT
392                                 fi
393                         done
394                         echo "  ;;" >>$SCRIPT
395                         echo "post-start)" >>$SCRIPT
396                         echo "  ;;" >>$SCRIPT
397                         echo "pre-stop)" >>$SCRIPT
398                         echo "  ;;" >>$SCRIPT
399                         echo "post-stop)" >>$SCRIPT
400                         for dir in $dir1 $dir2 $dir3 $dir4  none
401                         do
402                                 if [ "$dir" != "none" ] ; then
403                                         echo "  umount $VROOT/$dir" >>$SCRIPT
404                                 fi
405                         done
406                         echo "  ;;" >>$SCRIPT
407                         echo '*)' >>$SCRIPT
408                 echo '  echo $0 pre-start' >>$SCRIPT
409                         echo '  echo $0 pre-stop' >>$SCRIPT
410                         echo '  echo $0 post-start' >>$SCRIPT
411                         echo '  echo $0 post-stop' >>$SCRIPT
412                         echo "  ;;" >>$SCRIPT
413                         echo "esac" >>$SCRIPT
414                         chmod +x $SCRIPT
415
416                         LOG=/var/run/newvserver.log.$$
417                         if [ "$clone" = "/" ] ; then
418                                 # Unification does not work on / yet
419                                 $VSERVER_CMD $name build >$LOG
420                         elif [ "$clone" = "#rh7.2" ] ; then
421                                 check_cd "first RedHat 7.2 CD"
422                                 set_fstab $VROOT
423                                 installpkgs $LOG $USR_LIB_VSERVER/install-rh7.2 $name
424                         elif [ "$clone" = "#rh7.3m" -o "$clone" = "#rh7.3f" ] ; then
425                                 check_cd "first RedHat 7.3 CD"
426                                 set_fstab $VROOT
427                                 if [ "$clone" = "#rh7.3m" ] ;then
428                                         installpkgs $LOG $USR_LIB_VSERVER/install-rh7.3 $name minimum
429                                 else
430                                         installpkgs $LOG $USR_LIB_VSERVER/install-rh7.3 $name full
431                                 fi
432                         elif [ "$clone" = "#rh8.0m" -o "$clone" = "#rh8.0f" ] ; then
433                                 check_cd "first RedHat 8.0 CD"
434                                 set_fstab $VROOT
435                                 if [ "$clone" = "#rh8.0m" ] ;then
436                                         installpkgs $LOG $USR_LIB_VSERVER/install-rh8.0 $name minimum
437                                 else
438                                         installpkgs $LOG $USR_LIB_VSERVER/install-rh8.0 $name full
439                                 fi
440                         elif [ "$clone" = "#rh9.0m" -o "$clone" = "#rh9.0f" ] ; then
441                                 check_cd "first RedHat 9.0 CD"
442                                 set_fstab $VROOT
443                                 if [ "$clone" = "#rh9.0m" ] ;then
444                                         installpkgs $LOG $USR_LIB_VSERVER/install-rh9.0 $name minimum
445                                 else
446                                         installpkgs $LOG $USR_LIB_VSERVER/install-rh9.0 $name full
447                                 fi
448                         elif [ "$unify" = "0" ] ; then
449                                 cp -ax /vservers/$clone/. $VROOT/. >$LOG
450                         else
451                                 EXCLOPT=
452                                 for dir in $exdir1 $exdir2 $exdir3 $exdir4  $exdir5 $exdir6 none
453                                 do
454                                         if [ "$dir" != "none" ] ; then
455                                                 EXCLOPT="$EXCLOPT --excldir $dir"
456                                         fi
457                                 done
458                                 $USR_LIB_VSERVER/vbuild $EXCLOPT --stats /vservers/$clone $VROOT >$LOG
459                         fi
460                         rm -f $VROOT/var/run/utmp
461                         $USR_LIB_VSERVER/fakerunlevel 3 $VROOT/var/run/utmp
462                         test "$crond" = 1 && $VSERVER_CMD $name chkconfig crond on >/dev/null
463                         test "$httpd" = 1 && $VSERVER_CMD $name chkconfig httpd on >/dev/null
464                         test "$sshd" = 1 && $VSERVER_CMD $name chkconfig sshd on >/dev/null
465                         if [ "$cleansshd" = 1 ] ; then
466                                 echo Deleting sshd server keys >>$LOG
467                                 rm -f $VROOT/etc/ssh/*_key
468                                 rm -f $VROOT/etc/ssh/*_key.pub
469                         fi
470                         test "$syslog" = 1 && $VSERVER_CMD $name chkconfig syslog on >/dev/null
471                         test "$xinetd" = 1 && $VSERVER_CMD $name chkconfig xinetd on >/dev/null
472                         test "$nscd" = 1 && $VSERVER_CMD $name chkconfig nscd on >/dev/null
473                         host0=`echo $hostname | sed 's/\./ /g' | ( read a b; echo $a)`
474                         echo $ip $hostname $host0 localhost >$VROOT/etc/hosts
475                         RHNETWORK=$VROOT/etc/sysconfig/network
476                         if [ -f $RHNETWORK ] ; then
477                                 cat $RHNETWORK | grep -v HOSTNAME >/tmp/newvserver.tmp.$$
478                                 cp /tmp/newvserver.tmp.$$ $RHNETWORK
479                                 echo HOSTNAME=$hostname >>$RHNETWORK
480                         fi
481                         # Umount proc and /dev/pts
482                         $VSERVER_CMD $name stop >/dev/null
483                         ENDTIME=`date +%s`
484                         DURATION=`expr $ENDTIME - $STARTTIME`
485
486                         echo defval s1 Server $name was installed in $VROOT
487                         echo defval s1 The configuration file /etc/vservers/$name.conf was created
488                         echo defval s1 The script /etc/vservers/$name.sh was created
489                         echo defval s1 Vserver $name was created in $DURATION seconds
490                         echo defval s1 
491                         cat $LOG | while read line
492                         do
493                                 echo defval s1 $line
494                         done
495                         echo notice =s1
496                         rm -f $LOG
497                         # Finish some stuff: root password, account policies
498                         if [ -x $VROOT/usr/sbin/authconfig ] ; then
499                                 SHADOWOPT=
500                                 MD5OPT=
501                                 NISOPT=
502                                 LDAPOPT=
503                                 if [ "$usemd5" = "1" ] ; then
504                                         MD5OPT=--usemd5
505                                 fi
506                                 if [ "$useshadow" = "1" ] ; then
507                                         SHADOWOPT=--useshadow
508                                 fi
509                                 if [ "$nisserver" != "" ] ; then
510                                         NISOPT="--nisserver $nisserver --nisdomain $domainname"
511                                 fi
512                                 if [ "$ldapserver" != "" ] ; then
513                                         LDAPOPT="--ldapserver $ldapserver --ldapbasedn $ldapbasedn"
514                                 fi
515                                 $VSERVER_CMD $name exec /usr/sbin/authconfig \
516                                         --nostart --kickstart \
517                                         $SHADOWOPT $MD5OPT $NISOPT $LDAPOPT
518                         fi
519                         if [ "$pass1" != "" ] ; then
520                                 (echo $pass1; sleep 5; echo $pass1) \
521                                         | $VSERVER_CMD --silent $name exec passwd >/dev/null
522                         fi
523                         break
524                 fi
525         done
526         qecho end
527 }
528
529 dispatch