source: src-sh/pc-thinclient/pc-thinclient @ a11878a

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since a11878a was a11878a, checked in by Kris Moore <kris@…>, 15 months ago

Use the correct pc-sysinstall if user is running it manually from shell

  • Property mode set to 100644
File size: 15.7 KB
Line 
1#!/bin/sh
2#
3# Copyright 2012 Kris Moore / iXsystems
4# All rights reserved
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted providing that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26#
27#        Name: pc-thinclient
28# Description: Helper script to build / install the necessary bits to turn
29#              a PC-BSD system into a thin-client server
30#
31# Modified for external dhcp server support by Joe Maloney
32
33# Source our functions
34. /usr/local/share/pcbsd/scripts/functions.sh
35
36# Set some universal variables
37PROGDIR="/usr/local/share/pcbsd/pc-thinclient"
38DHCPPORT="isc-dhcp41-server"
39PXEWORLD="/usr/home/thinclient"
40WORLDPORTS="x11/xorg graphics/xv"
41export WORLDPORTS
42SYSVER="`uname -r | cut -d '-' -f 1-2`"
43
44# Start by sourcing /etc/profile
45# This grabs any HTTP_ / FTP_ PROXY variables
46. /etc/profile
47
48# Start configuring the base system
49check_configsystem() {
50        echo "Setting up system for PXE booting..."
51
52        # Setup the new pxeboot user with a default password
53        cat /etc/passwd | grep pxeboot >/dev/null 2>/dev/null
54        if [ "$?" != "0" ] ; then
55                echo "thinclient" | pw useradd -n "pxeboot" -h 0 -s /bin/tcsh -d ${PXEWORLD}/mnt/xorg-config -c "pxeboot"
56                chown -R pxeboot:pxeboot ${PXEWORLD}/mnt/xorg-config
57        fi
58
59        # Copy over the default dhcpd.conf file
60        cp ${PROGDIR}/resources/dhcpd/dhcpd.conf /usr/local/etc/dhcpd.conf
61
62        # Ask for the NIC we want to run on
63        while
64        z=1
65        do
66                echo "What NIC do you wish DHCPD to listen on? (I.E. re0)"
67                echo -e "nic) \c"
68                read NIC
69               
70                ifconfig $NIC >/dev/null 2>/dev/null
71                if [ $? -ne 0 -o -z "$NIC" ] ; then
72                        echo "Invalid nic entered, please try again!"
73                        sleep 1
74                else
75                        break
76                fi
77        done
78
79        # Save the rc.conf glue
80        cat /etc/rc.conf | grep "# pc-thinclient" >/dev/null 2>/dev/null
81        if [ "$?" != "0" ] ; then
82                echo "# pc-thinclient configuration
83dhcpd_enable=\"YES\"
84dhcpd_ifaces=\"${NIC}\"
85portmap_enable=\"YES\"
86nfs_server_enable=\"YES\"
87inetd_enable=\"YES\"
88ifconfig_${NIC}=\"192.168.2.2\"" >> /etc/rc.conf
89        fi
90
91        # Add firewall exception
92        if [ -e "/etc/pf.conf" ] ; then
93          cat /etc/pf.conf | grep "pass in on ${NIC} all" >/dev/null 2>/dev/null
94          if [ "$?" != "0" ] ; then
95                # Setup the firewall exclusion for this NIC
96                echo "pass in on ${NIC} all" >> /etc/pf.conf
97                /etc/rc.d/pf restart
98          fi
99        fi
100
101        # Add some entries for /etc/exports
102        cat /etc/exports 2>/dev/null | grep "$PXEWORLD" >/dev/null 2>/dev/null
103        if [ "$?" != "0" ] ; then
104                echo "$PXEWORLD -maproot=nobody -ro -network 192.168.2 -mask 255.255.255" >>/etc/exports
105        fi
106
107        # Setup tftp
108        cat /etc/inetd.conf | grep "$PXEWORLD" >/dev/null 2>/dev/null
109        if [ "$?" != "0" ] ; then
110                echo "tftp   dgram   udp     wait    root    /usr/libexec/tftpd      tftpd -l -s ${PXEWORLD}" >> /etc/inetd.conf
111        fi
112
113        # Setup rcpbind entries
114        cat /etc/hosts.allow 2>/dev/null | grep "192.168.2.0" >/dev/null 2>/dev/null
115        if [ "$?" != "0" ] ; then
116                sed  -i '' 's|rpcbind : ALL : deny|rpcbind : 192.168.2.0/255.255.255.0 : allow\
117portmap : 192.168.2.0/255.255.255.0 : allow\
118rpcbind : ALL : deny|' /etc/hosts.allow
119        fi
120
121        # Add a bulk of IPs to /etc/hosts this fixes bugs with RPC timeouts
122        # when mounting NFS
123        grep -q 'thinclient100' /etc/hosts
124        if [ $? -ne 0 ] ; then
125                i="100"
126                while
127                z="1"
128                do
129                        if [ "${i}" = "200" ]; then break; fi
130                        echo "192.168.2.${i}  thinclient${i}" >>/etc/hosts
131                        i="`expr ${i} + 1`"
132                done
133        fi
134
135        # Make sure the NIC is set to the right IP before bringing up dhcpd
136        ifconfig $NIC 192.168.2.2
137
138        # Start the services
139        cmds="/etc/rc.d/nfsd /etc/rc.d/inetd /usr/local/etc/rc.d/isc-dhcpd"
140        for _sC in $cmds
141        do
142                echo -e "Starting ${_sC}...\c"
143                ${_sC} restart >/dev/null 2>/dev/null
144                if [ "$?" != "0" ] ; then
145                        echo -e "FAILED! Please run try running it manually."
146                else
147                        echo -e "OK"
148                fi
149        done
150}
151
152# Start configuring the base system without DHCP
153check_configsystem_ignore_dhcp() {
154        echo "Setting up system for PXE booting..."
155
156        # Setup the new pxeboot user with a default password
157        cat /etc/passwd | grep pxeboot >/dev/null 2>/dev/null
158        if [ "$?" != "0" ] ; then
159                echo "thinclient" | pw useradd -n "pxeboot" -h 0 -s /bin/tcsh -d ${PXEWORLD}/mnt/xorg-config -c "pxeboot"
160                chown -R pxeboot:pxeboot ${PXEWORLD}/mnt/xorg-config
161        fi
162
163        # Ask for the NIC we want to run on
164        while
165        z=1
166        do
167                echo "What NIC do you wish to listen on? (I.E. re0)"
168                echo -e "nic) \c"
169                read NIC
170
171                ifconfig $NIC >/dev/null 2>/dev/null
172                if [ $? -ne 0 -o -z "$NIC" ] ; then
173                        echo "Invalid nic entered, please try again!"
174                        sleep 1
175                else
176                        break
177                fi
178        done
179       
180        # Ask for the IP Address to be used on the NIC for PXE booting
181        while
182        z=1
183        do
184                echo "What IP address will pc-thinclient be listening on? (I.E. 192.168.2.2)"
185                echo -e "ipaddr) \c"
186                read ipaddr
187        break
188        done
189                # Ask for the network id of the local subnet
190        while
191        z=1
192        do
193                echo "What is the network id for your local subnet? (I.E. 192.168.2.0)"
194                echo -e "netid) \c"
195                read netid
196        break
197        done
198       
199                # Ask for the network mask of the local subnet
200        while
201        z=1
202        do
203                echo "What is the network mask for your local subnet? (I.E. 255.255.255.0)"
204                echo -e "netmaskid) \c"
205                read netmaskid
206        break
207        done
208
209        # Save the rc.conf glue
210        cat /etc/rc.conf | grep "# pc-thinclient" >/dev/null 2>/dev/null
211        if [ "$?" != "0" ] ; then
212                echo "# pc-thinclient configuration
213portmap_enable=\"YES\"
214nfs_server_enable=\"YES\"
215inetd_enable=\"YES\"" >> /etc/rc.conf
216        fi
217       
218        # Add firewall exception
219        if [ -e "/etc/pf.conf" ] ; then
220          cat /etc/pf.conf | grep "pass in on ${NIC} all" >/dev/null 2>/dev/null
221          if [ "$?" != "0" ] ; then
222                # Setup the firewall exclusion for this NIC
223                echo "pass in on ${NIC} all" >> /etc/pf.conf
224          fi
225        fi
226
227        # Add some entries for /etc/exports based on manual user input
228        echo "$PXEWORLD -maproot=nobody -ro -network $netid -mask $netmaskid" >> /etc/exports
229
230        # Setup tftp
231        cat /etc/inetd.conf | grep "$PXEWORLD" >/dev/null 2>/dev/null
232        if [ "$?" != "0" ] ; then
233                echo "tftp   dgram   udp     wait    root    /usr/libexec/tftpd      tftpd -l -s ${PXEWORLD}" >> /etc/inetd.conf
234        fi
235       
236        # Setup rcpbind entries
237        sed -i -e "s|rpcbind : ALL : deny|rpcbind : $netid/$netmaskid : allow\\
238portmap : $netid/$netmaskid : allow\\
239rpcbind : ALL : deny|" /etc/hosts.allow
240
241        # Start the services
242        cmds="/etc/rc.d/nfsd /etc/rc.d/inetd"
243        for _sC in $cmds
244        do
245                echo -e "Starting ${_sC}...\c"
246                ${_sC} restart >/dev/null 2>/dev/null
247                if [ "$?" != "0" ] ; then
248                        echo -e "FAILED! Please run try running it manually."
249                else
250                        echo -e "OK"
251                fi
252        done
253}
254
255
256# Check if we need to install custom config
257check_installconfig() {
258        if [ -e "${PXEWORLD}/etc/scripts/tcslogin.sh" ] ; then return ; fi
259
260        # Lets copy over the /etc/scripts directory
261        rm -rf ${PXEWORLD}/etc/scripts >/dev/null 2>/dev/null
262        cp -r ${PROGDIR}/resources/scripts ${PXEWORLD}/etc/scripts
263
264        # Remove a few rc.d things we dont need on clients
265        rm ${PXEWORLD}/etc/rc.d/cron
266        rm ${PXEWORLD}/etc/rc.d/sendmail
267
268        # Lets copy over all the /etc/ files we need
269        cp ${PROGDIR}/resources/etc/fstab ${PXEWORLD}/etc/
270        cp ${PROGDIR}/resources/etc/gettytab ${PXEWORLD}/etc/
271        cp ${PROGDIR}/resources/etc/hosts ${PXEWORLD}/etc/
272        cp ${PROGDIR}/resources/etc/motd ${PXEWORLD}/etc/
273        cp ${PROGDIR}/resources/etc/rc.conf ${PXEWORLD}/etc/
274        cp ${PROGDIR}/resources/etc/ttys ${PXEWORLD}/etc/
275
276        # Copy over rc.d / boot / root files
277        cp ${PROGDIR}/resources/boot/beastie.4th ${PXEWORLD}/boot/
278        cp ${PROGDIR}/resources/root/dot.login ${PXEWORLD}/root/.login
279
280        # Create a few directories used on client
281        mkdir -p ${PXEWORLD}/mnt/xorg-config
282
283        # Create the diskless configuration
284        mkdir -p ${PXEWORLD}/conf/base
285        mkdir -p ${PXEWORLD}/conf/base/etc
286        mkdir -p ${PXEWORLD}/conf/base/var
287        mkdir -p ${PXEWORLD}/conf/base/root
288        echo "10m" > ${PXEWORLD}/conf/base/etc/md_size
289        echo "20m" > ${PXEWORLD}/conf/base/var/md_size
290        echo "30m" > ${PXEWORLD}/conf/base/root/md_size
291        chroot ${PXEWORLD} tar cvf conf/base/etc.cpio.gz --format cpio --gzip etc 2>/dev/null
292        chroot ${PXEWORLD} tar cvf conf/base/var.cpio.gz --exclude var/db/pkg --format cpio --gzip var 2>/dev/null
293        chroot ${PXEWORLD} tar cvf conf/base/root.cpio.gz --format cpio --gzip root 2>/dev/null
294
295        # Fix the ZFS zpool.cache
296        rmdir ${PXEWORLD}/boot/zfs 2>/dev/null
297        ln -fs /tmp ${PXEWORLD}/boot/zfs
298}
299
300# Check if we need to build the world environment
301check_worldports() {
302        mkdir ${PXEWORLD}/usr/local/etc 2>/dev/null
303        cp /etc/resolv.conf ${PXEWORLD}/etc/
304        cp /usr/local/etc/pkg.conf ${PXEWORLD}/usr/local/etc/
305        cp /usr/local/etc/pkg-pubkey.cert ${PXEWORLD}/usr/local/etc/
306
307        # Start by adding pcbsd-utils
308        pkg -c ${PXEWORLD} install -y pcbsd-utils
309       
310        # Remove old pc-sysinstall so we use new one in /usr/local/sbin
311        rm ${PXEWORLD}/usr/sbin/pc-sysinstall 2>/dev/null
312
313        # If we are not doing a desktop we can stop here
314        if [ "$SYSTYPE" != "desktop" ] ; then return; fi
315
316        if [ -e "${PXEWORLD}/usr/local/bin/xv" ] ; then return ; fi
317
318        if [ ! -d "${PXEWORLD}/usr/ports/x11/xorg" -a ! -d "/usr/ports/x11/xorg" ] ; then
319                exit_err "Missing /usr/ports/x11/xorg, please checkout ports tree to continue"
320        fi
321
322        if [ ! -d "${PXEWORLD}/usr/ports/x11/xorg" ] ; then
323                rm -rf "${PXEWORLD}/usr/ports"
324                echo "Copying /usr/ports -> ${PXEWORLD}/usr/ports"
325                cp -r /usr/ports ${PXEWORLD}/usr/ports
326        fi
327
328        # Building ports inside world
329        mount -t devfs devfs ${PXEWORLD}/dev
330        cp /etc/resolv.conf ${PXEWORLD}/etc/resolv.conf
331        echo "BATCH=yes" >> ${PXEWORLD}/etc/make.conf
332        echo '#!/bin/sh
333
334/etc/rc.d/ldconfig start
335chmod 777 /tmp
336MACHINE=i386 ; export MACHINE
337UNAME_p=i386 ; export UNAME_p
338UNAME_m=i386 ; export UNAME_m
339
340for p in $WORLDPORTS
341do
342        cd /usr/ports/$p
343        make install
344        if [ "$?" != "0" ] ; then
345                exit 1
346        fi
347done
348' > ${PXEWORLD}/.mkports.sh
349
350        chmod 755 ${PXEWORLD}/.mkports.sh
351        chroot ${PXEWORLD} /.mkports.sh
352        if [ "$?" != "0" ] ; then
353                exit_err "Failed building thinclient world ports!"
354        fi
355        rm ${PXEWORLD}/.mkports.sh
356        umount ${PXEWORLD}/dev
357
358}
359
360# Check if we need to build the world environment
361check_world() {
362  if [ -e "${PXEWORLD}/COPYRIGHT" ] ; then return ; fi
363       
364  mkdir -p "${PXEWORLD}"
365  cd "${PXEWORLD}"
366
367  # Default pcbsd.conf file
368  PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
369
370  # Set the system arch type
371  if [ "$SYSTYPE" = "desktop" ] ; then
372    # If building remote X server, we don't need to run amd64
373    ARCH="i386"
374  else
375    ARCH="`uname -m`"
376  fi
377
378  local dFiles="base.txz doc.txz kernel.txz games.txz"
379  if [ "$ARCH" = "amd64" ] ; then
380     dFiles="$dFiles lib32.txz"
381  fi
382
383  # To fetch the jail environment
384  echo "Fetching FreeBSD environment. This may take a while..."
385  for i in $dFiles
386  do
387    echo "Downloading ${SYSVER}/${ARCH}/dist/${i} ..."
388   
389    get_file_from_mirrors "/${SYSVER}/${ARCH}/dist/${i}" "$i" "iso"
390    [ $? -ne 0 ] && exit_err "Error while downloading the freebsd world."
391  done
392
393  # Save the archive as our example world environment
394  mkdir -p ${PXEWORLD}/installarchive/
395
396  echo "Extracting FreeBSD environment... This may take a while..."
397  # Extract dist files
398  for i in $dFiles
399  do
400    tar xvpf ${i} 2>/dev/null
401    if [ $? -ne 0 ] ; then exit_err "Failed extracting FreeBSD environment"; fi
402
403    # Save the archive file
404    mv ${i} ${PXEWORLD}/installarchive/
405  done
406
407}
408
409# Function to check if dhcpd is installed
410check_dhcpd() {
411        which dhcpd >/dev/null 2>/dev/null
412        if [ "$?" = "0" ] ; then return; fi
413
414        echo "Installing $DHCPPORT"
415        pkg install -y ${DHCPPORT}
416        if [ "$?" != "0" ] ; then exit_err "Failed installing ${DHCPPORT}"; fi
417}
418
419# Function to display what information to add to external DHCP server
420ignore_dhcpd() {
421        echo "Add the following information to your external DHCP Server"
422        echo "Will display here when this works"
423}
424
425# Function which checks and sets up the thinclient as an install server
426check_installdirs() {
427        if [ -e "${PXEWORLD}/installscripts/pc-sysinstall.example" ]; then
428           return
429        fi
430        touch ${PXEWORLD}/etc/installserver
431        mkdir ${PXEWORLD}/installscripts
432        cp ${PROGDIR}/resources/scripts/pc-sysinstall.example ${PXEWORLD}/installscripts/pc-sysinstall.example
433        echo "zfs_load=\"YES\"" > ${PXEWORLD}/boot/loader.conf
434        echo "geom_mirror_load=\"YES\"" >> ${PXEWORLD}/boot/loader.conf
435        echo "geom_eli_load=\"YES\"" >> ${PXEWORLD}/boot/loader.conf
436}
437
438do_removal() {
439        if [ -d "${PXEWORLD}" ] ; then
440                echo "Removing ${PXEWORLD}"
441                rm -rf ${PXEWORLD} 2>/dev/null
442                chflags -R noschg ${PXEWORLD} 2>/dev/null
443                rm -rf ${PXEWORLD} 2>/dev/null
444        fi
445}
446
447# Make sure we are root
448if [ `id -u` != "0" ] ; then exit_err "Must be run as root!"; fi
449
450# Check if we are removing the existing thinclient
451if [ "$1" = "-remove" -o "$1" = "remove" ] ;  then
452  do_removal
453  exit 0
454fi
455
456echo "$0 will install the components to convert this system into a thin-client server."
457echo -e "Continue? (Y/N) \c"
458read tmp
459if [ "$tmp" != "Y" -a "$tmp" != "y" ] ; then
460        exit 0
461fi
462
463echo "Do you wish to install the dhcpd server port or use an external server?"
464echo "If you wish to use an external server please make sure it supports adding" 
465echo "next server and bootfile name options."
466echo -e "(d/e) \c"
467read tmp
468if [ "$tmp" = "D" -o "$tmp" = "d" ] ; then
469   DHCPTYPE="internal"
470else
471   DHCPTYPE="external"
472fi
473
474echo "Do you wish to make this a remote X desktop server or install server?"
475echo -e "(r/i) \c"
476read tmp
477if [ "$tmp" = "I" -o "$tmp" = "i" ] ; then
478   SYSTYPE="install"
479else
480   SYSTYPE="desktop"
481fi
482
483
484if [ "$DHCPTYPE" = "internal" ] ; then
485  # Start by installing dhcpd
486  check_dhcpd
487else
488  # Install without dhcpd
489  ignore_dhcpd
490fi
491
492# Start by setting up a new buildworld
493check_world
494
495# Build the ports inside the world environment
496check_worldports
497
498if [ "$SYSTYPE" != "desktop" ] ; then
499  # Setup the installation directories
500  check_installdirs
501fi
502
503# Install the thinclient configuration files
504check_installconfig
505
506if [ "$DHCPTYPE" = "internal" ] ; then
507  # Tweak the base system to enable the thinclient
508  check_configsystem
509else
510  # Tweak the base system to enable the thinclient without dhcpd
511  check_configsystem_ignore_dhcp
512fi
513
514if [ "$SYSTYPE" = "desktop" ] ; then
515  echo ""
516  echo "You will now need to enable remote desktop."
517  echo "This can be done via the PC-BSD Control Panel -> GDM Configuration"
518  echo "or by manually editing /usr/local/etc/gdm/custom.conf"
519else
520  echo ""
521  echo "To perform system installations, place your custom pc-sysinstall scripts in:"
522  echo "/usr/home/thinclient/installscripts"
523  echo ""
524  echo "An example script is provided in the above directory"
525  echo ""
526  echo "For unattended installations, save your pc-sysinstall script as:"
527  echo "/usr/home/thinclient/installscripts/unattended.cfg"
528fi
529
530if [ "$DHCPTYPE" = "internal" ] ; then
531  echo ""
532  echo "Your system is now setup to do PXE booting!"
533  exit 0
534else
535  echo "You will need to modify the following options in your dhcp server:"
536  echo ""
537  echo "filename boot/pxeboot"
538  echo "next-server $ipaddr"
539  echo "option root-path $PXEWORLD"
540  echo ""
541  echo "Then you can begin to use PXE Boot."
542  exit 0
543fi
Note: See TracBrowser for help on using the repository browser.