source: src-sh/pc-thinclient/pc-thinclient @ 11c506b

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

Fix a cosmetic bug showing download mirror url

  • Property mode set to 100644
File size: 15.2 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          fi
98        fi
99
100        # Add some entries for /etc/exports
101        cat /etc/exports 2>/dev/null | grep "$PXEWORLD" >/dev/null 2>/dev/null
102        if [ "$?" != "0" ] ; then
103                echo "$PXEWORLD -maproot=nobody -ro -network 192.168.2 -mask 255.255.255" >>/etc/exports
104        fi
105
106        # Setup tftp
107        cat /etc/inetd.conf | grep "$PXEWORLD" >/dev/null 2>/dev/null
108        if [ "$?" != "0" ] ; then
109                echo "tftp   dgram   udp     wait    root    /usr/libexec/tftpd      tftpd -l -s ${PXEWORLD}" >> /etc/inetd.conf
110        fi
111
112        # Setup rcpbind entries
113        cat /etc/hosts.allow 2>/dev/null | grep "192.168.2.0" >/dev/null 2>/dev/null
114        if [ "$?" != "0" ] ; then
115                sed  -i '' 's|rpcbind : ALL : deny|rpcbind : 192.168.2.0/255.255.255.0 : allow\
116portmap : 192.168.2.0/255.255.255.0 : allow\
117rpcbind : ALL : deny|' /etc/hosts.allow
118        fi
119
120        # Add a bulk of IPs to /etc/hosts this fixes bugs with RPC timeouts
121        # when mounting NFS
122        grep -q 'thinclient100' /etc/hosts
123        if [ $? -ne 0 ] ; then
124                i="100"
125                while
126                z="1"
127                do
128                        if [ "${i}" = "200" ]; then break; fi
129                        echo "192.168.2.${i}  thinclient${i}" >>/etc/hosts
130                        i="`expr ${i} + 1`"
131                done
132        fi
133
134        # Make sure the NIC is set to the right IP before bringing up dhcpd
135        ifconfig $NIC 192.168.2.2
136
137        # Start the services
138        cmds="/etc/rc.d/nfsd /etc/rc.d/inetd /usr/local/etc/rc.d/isc-dhcpd"
139        for _sC in $cmds
140        do
141                echo -e "Starting ${_sC}...\c"
142                ${_sC} restart >/dev/null 2>/dev/null
143                if [ "$?" != "0" ] ; then
144                        echo -e "FAILED! Please run try running it manually."
145                else
146                        echo -e "OK"
147                fi
148        done
149}
150
151# Start configuring the base system without DHCP
152check_configsystem_ignore_dhcp() {
153        echo "Setting up system for PXE booting..."
154
155        # Setup the new pxeboot user with a default password
156        cat /etc/passwd | grep pxeboot >/dev/null 2>/dev/null
157        if [ "$?" != "0" ] ; then
158                echo "thinclient" | pw useradd -n "pxeboot" -h 0 -s /bin/tcsh -d ${PXEWORLD}/mnt/xorg-config -c "pxeboot"
159                chown -R pxeboot:pxeboot ${PXEWORLD}/mnt/xorg-config
160        fi
161
162        # Ask for the NIC we want to run on
163        while
164        z=1
165        do
166                echo "What NIC do you wish to listen on? (I.E. re0)"
167                echo -e "nic) \c"
168                read NIC
169
170                ifconfig $NIC >/dev/null 2>/dev/null
171                if [ $? -ne 0 -o -z "$NIC" ] ; then
172                        echo "Invalid nic entered, please try again!"
173                        sleep 1
174                else
175                        break
176                fi
177        done
178       
179        # Ask for the IP Address to be used on the NIC for PXE booting
180        while
181        z=1
182        do
183                echo "What IP address will pc-thinclient be listening on? (I.E. 192.168.2.2)"
184                echo -e "ipaddr) \c"
185                read ipaddr
186        break
187        done
188                # Ask for the network id of the local subnet
189        while
190        z=1
191        do
192                echo "What is the network id for your local subnet? (I.E. 192.168.2.0)"
193                echo -e "netid) \c"
194                read netid
195        break
196        done
197       
198                # Ask for the network mask of the local subnet
199        while
200        z=1
201        do
202                echo "What is the network mask for your local subnet? (I.E. 255.255.255.0)"
203                echo -e "netmaskid) \c"
204                read netmaskid
205        break
206        done
207
208        # Save the rc.conf glue
209        cat /etc/rc.conf | grep "# pc-thinclient" >/dev/null 2>/dev/null
210        if [ "$?" != "0" ] ; then
211                echo "# pc-thinclient configuration
212portmap_enable=\"YES\"
213nfs_server_enable=\"YES\"
214inetd_enable=\"YES\"" >> /etc/rc.conf
215        fi
216       
217        # Add firewall exception
218        if [ -e "/etc/pf.conf" ] ; then
219          cat /etc/pf.conf | grep "pass in on ${NIC} all" >/dev/null 2>/dev/null
220          if [ "$?" != "0" ] ; then
221                # Setup the firewall exclusion for this NIC
222                echo "pass in on ${NIC} all" >> /etc/pf.conf
223          fi
224        fi
225
226        # Add some entries for /etc/exports based on manual user input
227        echo "$PXEWORLD -maproot=nobody -ro -network $netid -mask $netmaskid" >> /etc/exports
228
229        # Setup tftp
230        cat /etc/inetd.conf | grep "$PXEWORLD" >/dev/null 2>/dev/null
231        if [ "$?" != "0" ] ; then
232                echo "tftp   dgram   udp     wait    root    /usr/libexec/tftpd      tftpd -l -s ${PXEWORLD}" >> /etc/inetd.conf
233        fi
234       
235        # Setup rcpbind entries
236        sed -i -e "s|rpcbind : ALL : deny|rpcbind : $netid/$netmaskid : allow\\
237portmap : $netid/$netmaskid : allow\\
238rpcbind : ALL : deny|" /etc/hosts.allow
239
240        # Start the services
241        cmds="/etc/rc.d/nfsd /etc/rc.d/inetd"
242        for _sC in $cmds
243        do
244                echo -e "Starting ${_sC}...\c"
245                ${_sC} restart >/dev/null 2>/dev/null
246                if [ "$?" != "0" ] ; then
247                        echo -e "FAILED! Please run try running it manually."
248                else
249                        echo -e "OK"
250                fi
251        done
252}
253
254
255# Check if we need to install custom config
256check_installconfig() {
257        if [ -e "${PXEWORLD}/etc/scripts/tcslogin.sh" ] ; then return ; fi
258
259        # Lets copy over the /etc/scripts directory
260        rm -rf ${PXEWORLD}/etc/scripts >/dev/null 2>/dev/null
261        cp -r ${PROGDIR}/resources/scripts ${PXEWORLD}/etc/scripts
262
263        # Remove a few rc.d things we dont need on clients
264        rm ${PXEWORLD}/etc/rc.d/cron
265        rm ${PXEWORLD}/etc/rc.d/sendmail
266
267        # Lets copy over all the /etc/ files we need
268        cp ${PROGDIR}/resources/etc/fstab ${PXEWORLD}/etc/
269        cp ${PROGDIR}/resources/etc/gettytab ${PXEWORLD}/etc/
270        cp ${PROGDIR}/resources/etc/hosts ${PXEWORLD}/etc/
271        cp ${PROGDIR}/resources/etc/motd ${PXEWORLD}/etc/
272        cp ${PROGDIR}/resources/etc/rc.conf ${PXEWORLD}/etc/
273        cp ${PROGDIR}/resources/etc/ttys ${PXEWORLD}/etc/
274
275        # Copy over rc.d / boot / root files
276        cp ${PROGDIR}/resources/boot/beastie.4th ${PXEWORLD}/boot/
277        cp ${PROGDIR}/resources/root/dot.login ${PXEWORLD}/root/.login
278
279        # Create a few directories used on client
280        mkdir -p ${PXEWORLD}/mnt/xorg-config
281
282        # Create the diskless configuration
283        mkdir -p ${PXEWORLD}/conf/base
284        mkdir -p ${PXEWORLD}/conf/base/etc
285        mkdir -p ${PXEWORLD}/conf/base/var
286        mkdir -p ${PXEWORLD}/conf/base/root
287        echo "10m" > ${PXEWORLD}/conf/base/etc/md_size
288        echo "20m" > ${PXEWORLD}/conf/base/var/md_size
289        echo "30m" > ${PXEWORLD}/conf/base/root/md_size
290        chroot ${PXEWORLD} tar cvf conf/base/etc.cpio.gz --format cpio --gzip etc 2>/dev/null
291        chroot ${PXEWORLD} tar cvf conf/base/var.cpio.gz --exclude var/db/pkg --format cpio --gzip var 2>/dev/null
292        chroot ${PXEWORLD} tar cvf conf/base/root.cpio.gz --format cpio --gzip root 2>/dev/null
293
294        # Fix the ZFS zpool.cache
295        rmdir ${PXEWORLD}/boot/zfs 2>/dev/null
296        ln -fs /tmp ${PXEWORLD}/boot/zfs
297}
298
299# Check if we need to build the world environment
300check_worldports() {
301        if [ -e "${PXEWORLD}/usr/local/bin/xv" ] ; then return ; fi
302
303        if [ ! -d "${PXEWORLD}/usr/ports/x11/xorg" -a ! -d "/usr/ports/x11/xorg" ] ; then
304                exit_err "Missing /usr/ports/x11/xorg, please checkout ports tree to continue"
305        fi
306
307        if [ ! -d "${PXEWORLD}/usr/ports/x11/xorg" ] ; then
308                rm -rf "${PXEWORLD}/usr/ports"
309                echo "Copying /usr/ports -> ${PXEWORLD}/usr/ports"
310                cp -r /usr/ports ${PXEWORLD}/usr/ports
311        fi
312
313        # Building ports inside world
314        mount -t devfs devfs ${PXEWORLD}/dev
315        cp /etc/resolv.conf ${PXEWORLD}/etc/resolv.conf
316        echo "BATCH=yes" >> ${PXEWORLD}/etc/make.conf
317        echo '#!/bin/sh
318
319/etc/rc.d/ldconfig start
320chmod 777 /tmp
321MACHINE=i386 ; export MACHINE
322UNAME_p=i386 ; export UNAME_p
323UNAME_m=i386 ; export UNAME_m
324
325for p in $WORLDPORTS
326do
327        cd /usr/ports/$p
328        make install
329        if [ "$?" != "0" ] ; then
330                exit 1
331        fi
332done
333' > ${PXEWORLD}/.mkports.sh
334
335        chmod 755 ${PXEWORLD}/.mkports.sh
336        chroot ${PXEWORLD} /.mkports.sh
337        if [ "$?" != "0" ] ; then
338                exit_err "Failed building thinclient world ports!"
339        fi
340        rm ${PXEWORLD}/.mkports.sh
341        umount ${PXEWORLD}/dev
342
343}
344
345# Check if we need to build the world environment
346check_world() {
347  if [ -e "${PXEWORLD}/COPYRIGHT" ] ; then return ; fi
348       
349  mkdir -p "${PXEWORLD}"
350  cd "${PXEWORLD}"
351
352  # Default pcbsd.conf file
353  PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
354
355  # Set the system arch type
356  if [ "$SYSTYPE" = "desktop" ] ; then
357    # If building remote X server, we don't need to run amd64
358    ARCH="i386"
359  else
360    ARCH="`uname -m`"
361  fi
362
363  local dFiles="base.txz doc.txz kernel.txz games.txz"
364  if [ "$ARCH" = "amd64" ] ; then
365     dFiles="$dFiles lib32.txz"
366  fi
367
368  # To fetch the jail environment
369  echo "Fetching FreeBSD environment. This may take a while..."
370  for i in $dFiles
371  do
372    echo "Downloading ${SYSVER}/${ARCH}/dist/${i} ..."
373   
374    get_file_from_mirrors "/${SYSVER}/${ARCH}/dist/${i}" "$i" "iso"
375    [ $? -ne 0 ] && exit_err "Error while downloading the freebsd world."
376  done
377
378  # Save the archive as our example world environment
379  mkdir -p ${PXEWORLD}/installarchive/
380
381  echo "Extracting FreeBSD environment... This may take a while..."
382  # Extract dist files
383  for i in $dFiles
384  do
385    tar xvpf ${i} 2>/dev/null
386    if [ $? -ne 0 ] ; then exit_err "Failed extracting FreeBSD environment"; fi
387
388    # Save the archive file
389    mv ${i} ${PXEWORLD}/installarchive/
390  done
391
392}
393
394# Function to check if dhcpd is installed
395check_dhcpd() {
396        which dhcpd >/dev/null 2>/dev/null
397        if [ "$?" = "0" ] ; then return; fi
398
399        echo "Installing $DHCPPORT"
400        pkg install -y ${DHCPPORT}
401        if [ "$?" != "0" ] ; then exit_err "Failed installing ${DHCPPORT}"; fi
402}
403
404# Function to display what information to add to external DHCP server
405ignore_dhcpd() {
406        echo "Add the following information to your external DHCP Server"
407        echo "Will display here when this works"
408}
409
410# Function which checks and sets up the thinclient as an install server
411check_installdirs() {
412        if [ -e "${PXEWORLD}/installscripts/pc-sysinstall.example" ]; then
413           return
414        fi
415        touch ${PXEWORLD}/etc/installserver
416        mkdir ${PXEWORLD}/installscripts
417        cp ${PROGDIR}/resources/scripts/pc-sysinstall.example ${PXEWORLD}/installscripts/pc-sysinstall.example
418        echo "zfs_load=\"YES\"" > ${PXEWORLD}/boot/loader.conf
419        echo "geom_mirror_load=\"YES\"" >> ${PXEWORLD}/boot/loader.conf
420        echo "geom_eli_load=\"YES\"" >> ${PXEWORLD}/boot/loader.conf
421}
422
423do_removal() {
424        if [ -d "${PXEWORLD}" ] ; then
425                echo "Removing ${PXEWORLD}"
426                rm -rf ${PXEWORLD} 2>/dev/null
427                chflags -R noschg ${PXEWORLD} 2>/dev/null
428                rm -rf ${PXEWORLD} 2>/dev/null
429        fi
430}
431
432# Make sure we are root
433if [ `id -u` != "0" ] ; then exit_err "Must be run as root!"; fi
434
435# Check if we are removing the existing thinclient
436if [ "$1" = "-remove" -o "$1" = "remove" ] ;  then
437  do_removal
438  exit 0
439fi
440
441echo "$0 will install the components to convert this system into a thin-client server."
442echo -e "Continue? (Y/N) \c"
443read tmp
444if [ "$tmp" != "Y" -a "$tmp" != "y" ] ; then
445        exit 0
446fi
447
448echo "Do you wish to install the dhcpd server port or use an external server?"
449echo "If you wish to use an external server please make sure it supports adding" 
450echo "next server and bootfile name options."
451echo -e "(d/e) \c"
452read tmp
453if [ "$tmp" = "D" -o "$tmp" = "d" ] ; then
454   DHCPTYPE="internal"
455else
456   DHCPTYPE="external"
457fi
458
459echo "Do you wish to make this a remote X desktop server or install server?"
460echo -e "(r/i) \c"
461read tmp
462if [ "$tmp" = "I" -o "$tmp" = "i" ] ; then
463   SYSTYPE="install"
464else
465   SYSTYPE="desktop"
466fi
467
468
469if [ "$DHCPTYPE" = "internal" ] ; then
470  # Start by installing dhcpd
471  check_dhcpd
472else
473  # Install without dhcpd
474  ignore_dhcpd
475fi
476
477# Start by setting up a new buildworld
478check_world
479
480if [ "$SYSTYPE" = "desktop" ] ; then
481  # Build the ports inside the world environment
482  check_worldports
483else
484  # Setup the installation directories
485  check_installdirs
486fi
487
488# Install the thinclient configuration files
489check_installconfig
490
491if [ "$DHCPTYPE" = "internal" ] ; then
492  # Tweak the base system to enable the thinclient
493  check_configsystem
494else
495  # Tweak the base system to enable the thinclient without dhcpd
496  check_configsystem_ignore_dhcp
497fi
498
499if [ "$SYSTYPE" = "desktop" ] ; then
500  echo ""
501  echo "You will now need to enable remote desktop."
502  echo "This can be done via the PC-BSD Control Panel -> GDM Configuration"
503  echo "or by manually editing /usr/local/etc/gdm/custom.conf"
504else
505  echo ""
506  echo "To perform system installations, place your custom pc-sysinstall scripts in:"
507  echo "/usr/home/thinclient/installscripts"
508  echo ""
509  echo "An example script is provided in the above directory"
510  echo ""
511  echo "For unattended installations, save your pc-sysinstall script as:"
512  echo "/usr/home/thinclient/installscripts/unattended.cfg"
513fi
514
515if [ "$DHCPTYPE" = "internal" ] ; then
516  echo ""
517  echo "Your system is now setup to do PXE booting!"
518  exit 0
519else
520  echo "You will need to modify the following options in your dhcp server:"
521  echo ""
522  echo "filename boot/pxeboot"
523  echo "next-server $ipaddr"
524  echo "option root-path $PXEWORLD"
525  echo ""
526  echo "Then you can begin to use PXE Boot."
527  exit 0
528fi
Note: See TracBrowser for help on using the repository browser.