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

releng/10.0.1
Last change on this file was 6f06854, checked in by Kris Moore <kris@…>, 3 months ago

Fix the boot-strapping of PKGNG 1.2.x when using pc-thinclient

  • Property mode set to 100644
File size: 16.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                /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# Check if the user wants to install packages for the webui
256check_webui() {
257        echo "PC-ThinClient includes a web-interface for client management."
258        echo "Would you like to install the Apache / PHP packages required?"
259        echo -e "default: (y)\c";
260        read ans
261        if [ "$ans" = "n" -o "$ans" = "N" ] ; then return; fi
262
263        pkg install apache22 php5-hash php5-session
264        if [ $? -ne 0 ] ; then
265                echo "Package install failed!"
266                echo "You may need to manually add apache, php5-hash and php5-session."
267        fi
268
269        # Make sure the config file exists
270        if [ ! -e "${PROGDIR}/resources/webui/config.php" ] ; then
271                cp ${PROGDIR}/resources/webui/config.php.dist ${PROGDIR}/resources/webui/config.php
272        fi
273
274        echo "All the webui files are located in: ${PROGDIR}/resources/webui"
275        echo "You will need to configure your web-server to serve this directory."
276        echo ""
277        echo "Please edit the file ${PROGDIR}/resources/webui/config.php to set the"
278        echo "user passwords / auth tokens for the site."
279}
280
281# Check if we need to install custom config
282check_installconfig() {
283        if [ -e "${PXEWORLD}/etc/scripts/tcslogin.sh" ] ; then return ; fi
284
285        # Lets copy over the /etc/scripts directory
286        rm -rf ${PXEWORLD}/etc/scripts >/dev/null 2>/dev/null
287        cp -r ${PROGDIR}/resources/scripts ${PXEWORLD}/etc/scripts
288
289        # Remove a few rc.d things we dont need on clients
290        rm ${PXEWORLD}/etc/rc.d/cron
291        rm ${PXEWORLD}/etc/rc.d/sendmail
292
293        # Lets copy over all the /etc/ files we need
294        cp ${PROGDIR}/resources/etc/fstab ${PXEWORLD}/etc/
295        cp ${PROGDIR}/resources/etc/gettytab ${PXEWORLD}/etc/
296        cp ${PROGDIR}/resources/etc/hosts ${PXEWORLD}/etc/
297        cp ${PROGDIR}/resources/etc/motd ${PXEWORLD}/etc/
298        cp ${PROGDIR}/resources/etc/rc.conf ${PXEWORLD}/etc/
299        cp ${PROGDIR}/resources/etc/ttys ${PXEWORLD}/etc/
300
301        # Copy over rc.d / boot / root files
302        cp ${PROGDIR}/resources/boot/beastie.4th ${PXEWORLD}/boot/
303        cp ${PROGDIR}/resources/root/dot.login ${PXEWORLD}/root/.login
304
305        # Create a few directories used on client
306        mkdir -p ${PXEWORLD}/mnt/xorg-config
307
308        # Create the diskless configuration
309        mkdir -p ${PXEWORLD}/conf/base
310        mkdir -p ${PXEWORLD}/conf/base/etc
311        mkdir -p ${PXEWORLD}/conf/base/var
312        mkdir -p ${PXEWORLD}/conf/base/root
313        echo "10m" > ${PXEWORLD}/conf/base/etc/md_size
314        echo "20m" > ${PXEWORLD}/conf/base/var/md_size
315        echo "30m" > ${PXEWORLD}/conf/base/root/md_size
316        chroot ${PXEWORLD} tar cvf conf/base/etc.cpio.gz --format cpio --gzip etc 2>/dev/null
317        chroot ${PXEWORLD} tar cvf conf/base/var.cpio.gz --exclude var/db/pkg --format cpio --gzip var 2>/dev/null
318        chroot ${PXEWORLD} tar cvf conf/base/root.cpio.gz --format cpio --gzip root 2>/dev/null
319
320        # Fix the ZFS zpool.cache
321        rmdir ${PXEWORLD}/boot/zfs 2>/dev/null
322        ln -fs /tmp ${PXEWORLD}/boot/zfs
323}
324
325# Check if we need to build the world environment
326check_worldports() {
327        mkdir ${PXEWORLD}/usr/local/etc 2>/dev/null
328        cp /etc/resolv.conf ${PXEWORLD}/etc/
329        cp /usr/local/etc/pkg.conf ${PXEWORLD}/usr/local/etc/
330        cp -r /usr/local/etc/pkg ${PXEWORLD}/usr/local/etc/
331
332        # Start by adding pcbsd-utils
333        rc_halt "pkg -c ${PXEWORLD} install -y pcbsd-utils"
334       
335        # Remove old pc-sysinstall so we use new one in /usr/local/sbin
336        rm ${PXEWORLD}/usr/sbin/pc-sysinstall 2>/dev/null
337
338        # If we are not doing a desktop we can stop here
339        if [ "$SYSTYPE" != "desktop" ] ; then return; fi
340
341        if [ -e "${PXEWORLD}/usr/local/bin/xv" ] ; then return ; fi
342
343        # Install Xorg
344        rc_halt "pkg -c ${PXEWORLD} install -y xorg"
345
346        # Need to install / use GDM on the base system
347        if [ ! -e "/usr/local/sbin/gdm" ] ; then
348                rc_halt "pkg install -y gdm"
349        fi
350
351        # Disable PCDM since it doesn't do XDMCP
352        grep -q '^pcdm_enable="NO"' /etc/rc.conf
353        if [ $? -ne 0 ] ; then
354                echo 'pcdm_enable="NO"' >> /etc/rc.conf
355        fi
356
357        # Enable GDM for its XDMCP support
358        grep -q '^gdm_enable="YES"' /etc/rc.conf
359        if [ $? -ne 0 ] ; then
360                echo 'gdm_enable="YES"' >> /etc/rc.conf
361        fi
362
363        # Copy GDM pam & rc files
364        cp ${PROGDIR}/resources/gdm/gdm-pam /usr/local/etc/pam.d/gdm
365        cp ${PROGDIR}/resources/gdm/gdm-rc /usr/local/etc/rc.d/gdm
366        cp ${PROGDIR}/resources/gdm/custom.conf /usr/local/etc/gdm/custom.conf
367       
368        # Re-extract the ports overlay data
369        pc-extractoverlay ports
370}
371
372# Check if we need to build the world environment
373check_world() {
374  if [ -e "${PXEWORLD}/COPYRIGHT" ] ; then return ; fi
375       
376  mkdir -p "${PXEWORLD}"
377  cd "${PXEWORLD}"
378
379  # Default pcbsd.conf file
380  PCBSD_ETCCONF="/usr/local/etc/pcbsd.conf"
381
382  # Set the system arch type
383  ARCH="`uname -m`"
384
385  local dFiles="base.txz doc.txz kernel.txz games.txz"
386  if [ "$ARCH" = "amd64" ] ; then
387     dFiles="$dFiles lib32.txz"
388  fi
389
390  # To fetch the jail environment
391  echo "Fetching FreeBSD environment. This may take a while..."
392  for i in $dFiles
393  do
394    echo "Downloading ${SYSVER}/${ARCH}/dist/${i} ..."
395   
396    get_file_from_mirrors "/${SYSVER}/${ARCH}/dist/${i}" "$i" "iso"
397    [ $? -ne 0 ] && exit_err "Error while downloading the freebsd world."
398  done
399
400  # Save the archive as our example world environment
401  mkdir -p ${PXEWORLD}/installarchive/
402
403  echo "Extracting FreeBSD environment... This may take a while..."
404  # Extract dist files
405  for i in $dFiles
406  do
407    tar xvpf ${i} 2>/dev/null
408    if [ $? -ne 0 ] ; then exit_err "Failed extracting FreeBSD environment"; fi
409
410    # Save the archive file
411    mv ${i} ${PXEWORLD}/installarchive/
412  done
413
414}
415
416# Function to check if dhcpd is installed
417check_dhcpd() {
418        which dhcpd >/dev/null 2>/dev/null
419        if [ "$?" = "0" ] ; then return; fi
420
421        echo "Installing $DHCPPORT"
422        rc_halt "pkg install -y ${DHCPPORT}"
423}
424
425# Function to display what information to add to external DHCP server
426ignore_dhcpd() {
427        echo "Add the following information to your external DHCP Server"
428        echo "Will display here when this works"
429}
430
431# Function which checks and sets up the thinclient as an install server
432check_installdirs() {
433        if [ -e "${PXEWORLD}/installscripts/pc-sysinstall.example" ]; then
434           return
435        fi
436        touch ${PXEWORLD}/etc/installserver
437        mkdir ${PXEWORLD}/installscripts
438        cp ${PROGDIR}/resources/scripts/pc-sysinstall.example ${PXEWORLD}/installscripts/pc-sysinstall.example
439        chown -R www:www ${PXEWORLD}/installscripts
440
441        echo "zfs_load=\"YES\"" > ${PXEWORLD}/boot/loader.conf
442        echo "geom_mirror_load=\"YES\"" >> ${PXEWORLD}/boot/loader.conf
443        echo "geom_eli_load=\"YES\"" >> ${PXEWORLD}/boot/loader.conf
444}
445
446do_removal() {
447        if [ -d "${PXEWORLD}" ] ; then
448                echo "Removing ${PXEWORLD}"
449                rm -rf ${PXEWORLD} 2>/dev/null
450                chflags -R noschg ${PXEWORLD} 2>/dev/null
451                rm -rf ${PXEWORLD} 2>/dev/null
452        fi
453}
454
455# Make sure we are root
456if [ `id -u` != "0" ] ; then exit_err "Must be run as root!"; fi
457
458# Check if we are removing the existing thinclient
459if [ "$1" = "-remove" -o "$1" = "remove" ] ;  then
460  do_removal
461  exit 0
462fi
463
464echo "$0 will install the components to convert this system into a thin-client server."
465echo -e "Continue? (Y/N) \c"
466read tmp
467if [ "$tmp" != "Y" -a "$tmp" != "y" ] ; then
468        exit 0
469fi
470
471echo "Do you wish to install the dhcpd server port or use an external server?"
472echo "If you wish to use an external server please make sure it supports adding" 
473echo "next server and bootfile name options."
474echo -e "(d/e) \c"
475read tmp
476if [ "$tmp" = "D" -o "$tmp" = "d" ] ; then
477   DHCPTYPE="internal"
478else
479   DHCPTYPE="external"
480fi
481
482echo "Do you wish to make this a remote X desktop server or install server?"
483echo -e "(r/i) \c"
484read tmp
485if [ "$tmp" = "I" -o "$tmp" = "i" ] ; then
486   SYSTYPE="install"
487else
488   SYSTYPE="desktop"
489fi
490
491
492if [ "$DHCPTYPE" = "internal" ] ; then
493  # Start by installing dhcpd
494  check_dhcpd
495else
496  # Install without dhcpd
497  ignore_dhcpd
498fi
499
500# Start by setting up a new buildworld
501check_world
502
503# Build the ports inside the world environment
504check_worldports
505
506if [ "$SYSTYPE" != "desktop" ] ; then
507  # Setup the installation directories
508  check_installdirs
509
510  # Ask if they want to use the WebUI
511  check_webui
512fi
513
514# Install the thinclient configuration files
515check_installconfig
516
517if [ "$DHCPTYPE" = "internal" ] ; then
518  # Tweak the base system to enable the thinclient
519  check_configsystem
520else
521  # Tweak the base system to enable the thinclient without dhcpd
522  check_configsystem_ignore_dhcp
523fi
524
525if [ "$SYSTYPE" = "desktop" ] ; then
526  echo ""
527  echo "You will need to reboot the system for the login manager changes"
528  echo "to take effect."
529else
530  echo ""
531  echo "To perform system installations, place your custom pc-sysinstall scripts in:"
532  echo "/usr/home/thinclient/installscripts"
533  echo ""
534  echo "An example script is provided in the above directory"
535  echo ""
536  echo "For unattended installations, save your pc-sysinstall script as:"
537  echo "/usr/home/thinclient/installscripts/unattended.cfg"
538fi
539
540if [ "$DHCPTYPE" = "internal" ] ; then
541  echo ""
542  echo "Your system is now setup to do PXE booting!"
543  exit 0
544else
545  echo "You will need to modify the following options in your dhcp server:"
546  echo ""
547  echo "filename boot/pxeboot"
548  echo "next-server $ipaddr"
549  echo "option root-path $PXEWORLD"
550  echo ""
551  echo "Then you can begin to use PXE Boot."
552  exit 0
553fi
Note: See TracBrowser for help on using the repository browser.