source: src-sh/pc-thinclient/pc-thinclient @ 34fdbb5

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

Merge branch 'master' of https://github.com/pkgdemon/pcbsd

  • Property mode set to 100644
File size: 15.3 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 mirror URL
356  get_mirror
357  MIRRORURL="$VAL"
358
359  # Set the system arch type
360  if [ "$SYSTYPE" = "desktop" ] ; then
361    # If building remote X server, we don't need to run amd64
362    ARCH="i386"
363  else
364    ARCH="`uname -m`"
365  fi
366
367  local dFiles="base.txz doc.txz kernel.txz games.txz"
368  if [ "$ARCH" = "amd64" ] ; then
369     dFiles="$dFiles lib32.txz"
370  fi
371
372  # To fetch the jail environment
373  echo "Fetching FreeBSD environment. This may take a while..."
374  for i in $dFiles
375  do
376    echo "Downloading ${MIRRORURL}/${SYSVER}/${ARCH}/dist/${i} ..."
377   
378    get_file_from_mirrors "/${SYSVER}/${ARCH}/dist/${i}" "$i" "iso"
379    [ $? -ne 0 ] && exit_err "Error while downloading the freebsd world."
380  done
381
382  # Save the archive as our example world environment
383  mkdir -p ${PXEWORLD}/installarchive/
384
385  echo "Extracting FreeBSD environment... This may take a while..."
386  # Extract dist files
387  for i in $dFiles
388  do
389    tar xvpf ${i} 2>/dev/null
390    if [ $? -ne 0 ] ; then exit_err "Failed extracting FreeBSD environment"; fi
391
392    # Save the archive file
393    mv ${i} ${PXEWORLD}/installarchive/
394  done
395
396}
397
398# Function to check if dhcpd is installed
399check_dhcpd() {
400        which dhcpd >/dev/null 2>/dev/null
401        if [ "$?" = "0" ] ; then return; fi
402
403        echo "Installing $DHCPPORT"
404        pkg install -y ${DHCPPORT}
405        if [ "$?" != "0" ] ; then exit_err "Failed installing ${DHCPPORT}"; fi
406}
407
408# Function to display what information to add to external DHCP server
409ignore_dhcpd() {
410        echo "Add the following information to your external DHCP Server"
411        echo "Will display here when this works"
412}
413
414# Function which checks and sets up the thinclient as an install server
415check_installdirs() {
416        if [ -e "${PXEWORLD}/installscripts/pc-sysinstall.example" ]; then
417           return
418        fi
419        touch ${PXEWORLD}/etc/installserver
420        mkdir ${PXEWORLD}/installscripts
421        cp ${PROGDIR}/resources/scripts/pc-sysinstall.example ${PXEWORLD}/installscripts/pc-sysinstall.example
422        echo "zfs_load=\"YES\"" > ${PXEWORLD}/boot/loader.conf
423        echo "geom_mirror_load=\"YES\"" >> ${PXEWORLD}/boot/loader.conf
424        echo "geom_eli_load=\"YES\"" >> ${PXEWORLD}/boot/loader.conf
425}
426
427do_removal() {
428        if [ -d "${PXEWORLD}" ] ; then
429                echo "Removing ${PXEWORLD}"
430                rm -rf ${PXEWORLD} 2>/dev/null
431                chflags -R noschg ${PXEWORLD} 2>/dev/null
432                rm -rf ${PXEWORLD} 2>/dev/null
433        fi
434}
435
436# Make sure we are root
437if [ `id -u` != "0" ] ; then exit_err "Must be run as root!"; fi
438
439# Check if we are removing the existing thinclient
440if [ "$1" = "-remove" -o "$1" = "remove" ] ;  then
441  do_removal
442  exit 0
443fi
444
445echo "$0 will install the components to convert this system into a thin-client server."
446echo -e "Continue? (Y/N) \c"
447read tmp
448if [ "$tmp" != "Y" -a "$tmp" != "y" ] ; then
449        exit 0
450fi
451
452echo "Do you wish to install the dhcpd server port or use an external server?"
453echo "If you wish to use an external server please make sure it supports adding" 
454echo "next server and bootfile name options."
455echo -e "(d/e) \c"
456read tmp
457if [ "$tmp" = "D" -o "$tmp" = "d" ] ; then
458   DHCPTYPE="internal"
459else
460   DHCPTYPE="external"
461fi
462
463echo "Do you wish to make this a remote X desktop server or install server?"
464echo -e "(r/i) \c"
465read tmp
466if [ "$tmp" = "I" -o "$tmp" = "i" ] ; then
467   SYSTYPE="install"
468else
469   SYSTYPE="desktop"
470fi
471
472
473if [ "$DHCPTYPE" = "internal" ] ; then
474  # Start by installing dhcpd
475  check_dhcpd
476else
477  # Install without dhcpd
478  ignore_dhcpd
479
480# Start by setting up a new buildworld
481check_world
482
483if [ "$SYSTYPE" = "desktop" ] ; then
484  # Build the ports inside the world environment
485  check_worldports
486else
487  # Setup the installation directories
488  check_installdirs
489fi
490
491# Install the thinclient configuration files
492check_installconfig
493
494if [ "$DHCPTYPE" = "internal" ] ; then
495  # Tweak the base system to enable the thinclient
496  check_configsystem
497else
498  # Tweak the base system to enable the thinclient without dhcpd
499  check_configsystem_ignore_dhcp
500fi
501
502if [ "$SYSTYPE" = "desktop" ] ; then
503  echo ""
504  echo "You will now need to enable remote desktop."
505  echo "This can be done via the PC-BSD Control Panel -> GDM Configuration"
506  echo "or by manually editing /usr/local/etc/gdm/custom.conf"
507else
508  echo ""
509  echo "To perform system installations, place your custom pc-sysinstall scripts in:"
510  echo "/usr/home/thinclient/installscripts"
511  echo ""
512  echo "An example script is provided in the above directory"
513  echo ""
514  echo "For unattended installations, save your pc-sysinstall script as:"
515  echo "/usr/home/thinclient/installscripts/unattended.cfg"
516fi
517
518if [ "$DHCPTYPE" = "internal" ] ; then
519  echo ""
520  echo "Your system is now setup to do PXE booting!"
521  exit 0
522else
523  echo "You will need to modify the following options in your dhcp server:"
524  echo ""
525  echo "filename boot/pxeboot"
526  echo "next-server $ipaddr"
527  echo "option root-path $PXEWORLD"
528  echo ""
529  echo "Then you can begin to use PXE Boot."
530  exit 0
531fi
532fi
Note: See TracBrowser for help on using the repository browser.