]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/tools/tinybsd/tinybsd
This commit was generated by cvs2svn to compensate for changes in r171577,
[FreeBSD/FreeBSD.git] / tools / tools / tinybsd / tinybsd
1 #!/bin/sh -
2 # Copyright (c) 2006 Jean Milanez Melo <jmelo@freebsdbrasil.com.br>
3 #                                      <jmelo@FreeBSD.org>
4 #                    Patrick Tracanelli <eksffa@freebsdbrasil.com.br>
5 #
6 # $FreeBSD$
7 #set -xv
8 CURRENTDIR=/usr/src/tools/tools/tinybsd
9 if [ ! -d $CURRENTDIR ]
10 then
11   CURRENTDIR=`pwd`
12 else
13   cd $CURRENTDIR
14 fi
15 WORKDIR=/usr/obj/tinybsdbuild
16 KERNCONF=TINYBSD
17 BASEFILE="tinybsd.basefiles"
18 PORTSFILE="tinybsd.ports"
19 PORTSDIR=/usr/ports
20 PKGDIRS=/tmp/pkg.dirs
21 PKGFILES=/tmp/pkg.files
22 DEFINSTARGS="-o 0 -g 0 -m 555"
23 TS="=====>"
24
25 splitarg1 () {
26    local IFS
27    IFS='='
28    set $1
29    echo $1
30 }
31
32 splitarg2 () {
33    local IFS
34    IFS='='
35    set $1
36    echo $2
37 }
38
39 getargs () {
40  ARGS="$*"
41  for arg in $* 
42  do
43    ARG=`splitarg1 $arg`
44    VAL=`splitarg2 $arg`
45    case $ARG in
46      sectors)
47         SECTUNIT=$VAL
48         ;;
49      heads)
50         TRACKCYL=$VAL 
51         ;;
52      spt)
53         SECTRACK=$VAL
54         ;;
55      conf)
56         CONF=$VAL
57         ;;
58      mfsroot)
59         MFSROOT=$VAL
60         ;;
61      image)
62         IMG=$VAL
63         ;;
64      batch)
65         NO_PROMPTS="YES"
66         ;;
67      new)
68         NO_READ="YES"
69         ;;
70      *)
71          usage
72          ;;
73     esac
74  done
75 }
76
77 usage () {
78     echo "Woops
79     Usage: $0 sectors=<size of media> [80000]
80               heads=<heads according to firmware>  [4]
81               spt=<sectors per track according to firmware> [32]
82               conf=<configuration name> (see conf/name) [default]
83               mfsroot[=<yes|no>] [no]
84               image=<tinybsd image name> [tinybsd.bin]
85               batch[=<anything>]  (do not ask interactively)
86               new[=<anything>]  (do not read previous values)
87
88      Examples:
89     $0 sectors=65536 heads=8 spt=16 conf=wireless mfsroot=yes image=myimage.img batch
90
91      Default values are set in the program.
92      Environment values override defaults.
93      Previous values override environment values but can be disabled.
94      Command arguments override previous values.
95      Interactive values override command arguments but can be disabled. 
96
97      Run diskinfo(8) -v against your CF device to get correct information
98      about your disk. USB keys do not need any specific geometry"
99     exit 1
100 }
101
102 ########
103 # Load variables from stdin (could be a file)
104 # Look for lines that match foo=bar
105 # do not run the file.. that is asking for trouble
106 ########
107 loadvars () {
108   while :
109   do
110     OIFS=$IFS
111     IFS="="
112     if read PART1 PART2
113     then
114       IFS="$OIFS"
115       case "$PART1" in
116       \#*)
117         ;;
118       "")
119         ;;
120       *)
121         set "${PART1}"
122         if [ $# = "1" ]
123         then
124           eval "${PART1}='${PART2}'"
125         fi
126         ;;
127       esac
128     else
129       IFS="$OIFS"
130       return 0
131     fi
132   done
133 }
134
135 ########
136 # get values from the user
137 ########
138 confirm_action(){
139     local ANSWER
140     local MESSAGE
141     ANSWER=$1
142     MESSAGE=$2
143     if [ "$NO_PROMPTS" != "YES" ]
144     then
145         echo -n "$MESSAGE [$ANSWER] " > /dev/tty
146         read result
147         [ "$result" != "" ] && ANSWER=$result
148     fi
149
150     ANSWER=`eval "echo $ANSWER"`
151     echo $ANSWER
152 }
153
154 ########
155 # These are only used the VERY first time you run the program (on this machine)
156 ########
157 setdefaults () {
158   NO_PROMPTS=${NO_PROMPTS:-NO}
159   NO_READ=${NO_READ:-NO}
160   SECTUNIT=${SECTUNIT:-80000}; export SECTUNIT
161   TRACKCYL=${TRACKCYL:-4}; export TRACKCYL
162   SECTRACK=${SECTRACK:-32}; export SECTRACK
163   CONF=${CONF:-default}; export CONF
164   MFSROOT=${MFSROOT:-NO}; export MFSROOT
165   IMG=${IMG:-tinybsd.bin}; export IMG
166
167 }
168
169 #######
170 # get ourselves set up.
171 # Partly by reading config files and partly from asking questions.
172 #######
173 loadconfig () {
174   if [ "${NO_READ}" = "YES" ]
175   then
176     return
177   fi
178
179   HOSTNAME=`hostname`
180   HOSTPART=${HOSTNAME%%.*}
181   FILENAME=".tinybsd.${HOSTPART}.${USER}"
182   FULLFILENAME=$HOME/$FILENAME
183
184   if [ -f ${FULLFILENAME} ]
185   then
186     loadvars <${FULLFILENAME}
187   fi
188
189   SECTUNIT=`confirm_action "$SECTUNIT" "512 byte sectors per unit?"`
190   TRACKCYL=`confirm_action "$TRACKCYL" "Tracks per cylinder?"`
191   SECTRACK=`confirm_action "$SECTRACK" "Sectors per track?"`
192   while :
193   do
194     echo "The following configurations exist:"
195     ls -l conf|awk '/^d/{print "    ",$9}'|grep -v CVS
196     CONF=`confirm_action "$CONF" "Configuration name?"`
197     if [ ! -d "${CURRENTDIR}/conf/$CONF" ]
198     then
199       echo "${TS} Error: Could not find config (${CONF})"
200       if [ "$NO_PROMPTS" = "YES" ]
201       then
202         exit 1
203       fi
204     else
205       break
206     fi
207   done
208   MFSROOT=`confirm_action "$MFSROOT" "Use an MFSROOT? (YES/NO)"`
209   IMG=`confirm_action "$IMG" "Image file to generate?"`
210
211 # example of formatted value (NNN in this case)
212 #  #condition and format the number
213 #  if [ -z "${BUILDNUM}" ]
214 #  then
215 #    echo "Starting with build 001"
216 #    BUILDNUM="001"
217 #  else
218 #    BUILDNUM=`printf "%03d\n" $(($BUILDNUM))`
219 #  fi
220
221
222 }
223
224 saveconfig () {
225   HOSTNAME=`hostname`
226   HOSTPART=${HOSTNAME%%.*}
227   FILENAME=".tinybsd.${HOSTPART}.${USER}"
228   FULLFILENAME=$HOME/$FILENAME
229   (
230     echo "# written by tinybsd" `date` 
231     echo "SECTUNIT=${SECTUNIT}"
232     echo "TRACKCYL=${TRACKCYL}"
233     echo "SECTRACK=${SECTRACK}"
234     echo "CONF=${CONF}"
235     echo "MFSROOT=${MFSROOT:-NO}"
236     echo "IMG=${IMG}"
237   ) >${FULLFILENAME}
238 }
239
240 check_alt_imgname() {
241         if [ ${IMG} = 'tinybsd.bin' ]
242         then
243                 echo "${TS} Alternative image name not set; defaulting to 'tinybsd.bin'"
244         fi
245 }
246
247 rotate_buidlog() {
248         mv -f ${HOME}/tinybsd.log ${HOME}/tinybsd.log.old
249 }
250
251 remove_workdir() {
252         chflags -R noschg ${WORKDIR}
253         echo "${TS} Removing "${WORKDIR}
254         rm -rf ${WORKDIR}
255         echo "${TS} Removing Build Kernel Directory"
256         rm -rf /usr/obj/usr/src/sys/${KERNCONF}
257         echo "${TS}  done."
258 }
259
260
261 prework() {
262         remove_workdir
263         mkdir -p ${WORKDIR}
264 }
265
266
267 create_tree() {
268         echo "${TS} Creating directory hierarchy... "
269         mtree -deU -f /etc/mtree/BSD.root.dist -p ${WORKDIR}
270         mtree -deU -f /etc/mtree/BSD.usr.dist -p ${WORKDIR}/usr
271         mtree -deU -f /etc/mtree/BSD.local.dist -p ${WORKDIR}/usr/local
272         mtree -deU -f /etc/mtree/BSD.var.dist -p ${WORKDIR}/var
273 }
274
275 copy_binaries() {
276         cd ${CURRENTDIR}/conf/${CONF}
277
278         for file in `cat ${BASEFILE} | grep -v "#" | \
279                 cut -f1 -d":" | sort | uniq` ; do
280                 echo "${TS} Copying "/${file}" to "${WORKDIR}/${file} 
281                 cp -fp /${file} ${WORKDIR}/${file} ;
282         done
283 }
284
285 install_ports() {
286         for portname in `cat ${PORTSFILE} | grep -v '#'` ; do
287             cd ${PORTSDIR}/${portname}
288             pkgname=`make -V PKGNAME`
289             pkg_info -VQ ${pkgname}
290             install=`echo $?`
291             if [ ${install} -eq 0 ] ; then
292                echo "$portname is already installed..."
293                create_missingdir
294                copy_ports
295               else
296                 make install clean
297                 create_missingdir
298                 copy_ports
299             fi
300         done
301 }
302
303 create_missingdir() {
304 pkg_info -L ${pkgname} | egrep -v '(Information|Files|www|share|doc|man|include)' | sort | uniq >> ${PKGDIRS}
305         for dir in `cat ${PKGDIRS}`; do
306           if [ ! -d `dirname ${WORKDIR}/${dir}` ] ; then
307             mkdir -p `dirname ${WORKDIR}/${dir}`
308           fi
309         done
310         rm ${PKGDIRS}
311 }
312
313 copy_ports() {
314 pkg_info -L ${pkgname} | egrep -v '(Information|Files|www|share|doc|man|include)' >> ${PKGFILES}
315         for port in `cat ${PKGFILES}` ; do
316                 echo "${TS} Copying "${port}" to "${WORKDIR}${port}
317                 cp -fp ${port} ${WORKDIR}${port} ;
318         done
319 }
320
321 make_kernel() {
322         echo "${TS} Building customized tiny beastie kernel... "
323         cp -p ${CURRENTDIR}/conf/${CONF}/${KERNCONF} /usr/src/sys/i386/conf
324         cd /usr/src
325         make buildkernel KERNCONF=${KERNCONF} || exit 1
326         gzip -9 /usr/obj/usr/src/sys/${KERNCONF}/kernel
327         install ${DEFINSTARGS} /usr/obj/usr/src/sys/${KERNCONF}/kernel.gz ${WORKDIR}/boot/kernel/
328         install ${DEFINSTARGS} \
329           /usr/obj/usr/src/sys/${KERNCONF}/modules/usr/src/sys/modules/acpi/acpi/acpi.ko \
330             ${WORKDIR}/boot/kernel
331         install -o 0 -g 0 -m 444 /sys/i386/conf/GENERIC.hints ${WORKDIR}/boot/device.hints
332 }
333
334 copy_libraries() {
335         TDEPFILE="`mktemp -t deps`"
336         TDEPFILES="`mktemp -t depsymlnk`"
337
338         cd ${CURRENTDIR}/conf/${CONF}
339         for file in `cat ${BASEFILE} ${PKGFILES} | grep -v "#" | cut -f1 -d":"`; do
340                 ldd -f "%p\n" /${file} >> ${TDEPFILE} ; # don't worry on progs been "not dynamic"
341         done
342
343         rm ${PKGFILES}
344
345         for libdeplib in `cat ${TDEPFILE} | sort | uniq`; do
346                 ldd -f "%p\n" /${libdeplib} >> ${TDEPFILE} ;
347         done
348
349         for pamdep in `ls -1 /usr/lib/pam*`; do
350                 echo $pamdep >> ${TDEPFILE} ;
351                 ldd -f "%p\n" /${pamdep} >> ${TDEPFILE} ;
352         done    
353
354         for lib in `cat ${TDEPFILE} | sort | uniq`; do
355                 echo "${TS} Copying "${lib}" to "${WORKDIR}${lib}
356                 cp -fp ${lib} ${WORKDIR}${lib} ;
357         done
358
359         for depsymlink in `cat ${TDEPFILE}`; do
360                 echo "${TS} Checking if ${depsymlink} is a symbolic link"
361                 /bin/ls -l $depsymlink | grep "\->" | awk '{print $11":"$9}' >> ${TDEPFILES}
362         done
363
364         for i in `cat ${TDEPFILES}`; do
365                 SOURCE_FILE=`echo $i | awk -F ":" '{print $1}'`
366                 TARGET_FILE=`echo $i | awk -F ":" '{print $2}'`
367
368                 echo "${TS} Unlinking ${WORKDIR}${TARGET_FILE}"
369                 chroot ${WORKDIR} /bin/chflags 0 ${TARGET_FILE}
370                 chroot ${WORKDIR} /bin/rm -f ${TARGET_FILE}
371
372                 echo "${TS} Symlinking ${SOURCE_FILE} to ${TARGET_FILE}"
373                 chroot ${WORKDIR} /bin/ln -s ${SOURCE_FILE} ${TARGET_FILE}
374         done
375
376         echo -n "${TS} Unlinking "
377         rm -fv ${TDEPFILE} ${TDEPFILES}
378 }
379
380 deinstall_ports() {
381         for portname in `cat ${PORTSFILE} | grep -v '#'` ; do
382             cd ${PORTSDIR}/${portname}    
383              if [ $? -ne ${install} ] ; then
384                make deinstall
385              fi
386         done
387 }
388
389 create_etc() {
390         cd /usr/src/etc/sendmail/
391         make freebsd.cf freebsd.submit.cf
392
393         cd /usr/src/etc/
394         mkdir -p ${WORKDIR}/var/named/etc/namedb
395         make distribution DESTDIR=${WORKDIR}
396 }
397
398 create_ssh_keys() {
399         echo "Creating ssh keys..."
400         ssh-keygen -t rsa1 -b 1024  -f ${WORKDIR}/etc/ssh/ssh_host_key -N ''
401         ssh-keygen -t dsa -f ${WORKDIR}/etc/ssh/ssh_host_dsa_key -N ''
402         ssh-keygen -t rsa -f ${WORKDIR}/etc/ssh/ssh_host_rsa_key -N ''
403 }
404
405 personal_conf() {
406         echo "${TS} Copying your custom configuration on conf/ ..."
407         for custom in `find ${CURRENTDIR}/conf/${CONF}/ -type d -depth 1 \! -name CVS`; do
408                 cp -Rp ${custom}/* ${WORKDIR}/${custom#${CURRENTDIR}/conf/${CONF}/}/
409         done
410
411         if [ -f ${CURRENTDIR}/conf/${CONF}/boot.config ]; then
412                 cp ${CURRENTDIR}/conf/${CONF}/boot.config ${WORKDIR}/boot.config
413         fi
414 }
415
416 symlinks() {
417 #set -xv
418         for i in `cat ${BASEFILE} ${PORTSFILE} | grep -v "#" | grep ":"`; do
419                 SOURCE_FILE=`echo $i | awk -F ":" {'print $1'}`
420                 TARGET_FILE=`echo $i | awk -F ":" {'print $2'}`
421                 chroot ${WORKDIR} /bin/ln -vs /${SOURCE_FILE} ${TARGET_FILE}
422         done
423 #set +xv
424 }
425
426
427 create_image() {
428         VNODEFILE=`mktemp -t tinybsd`
429         IMGMNT=`mktemp -d -t tinybsd`
430
431         dd if=/dev/zero of=${VNODEFILE} count=${SECTUNIT}
432
433         MD=`mdconfig -a -t vnode -f ${VNODEFILE} -x ${SECTRACK} -y ${TRACKCYL}`
434
435         diskinfo -v /dev/${MD}
436
437         fdisk -I /dev/${MD}
438         fdisk /dev/${MD}
439
440         cp -p /boot/boot0 ${WORKDIR}/boot/boot0
441         bsdlabel -w -B /dev/${MD}
442         newfs -O2 -U /dev/${MD}a
443
444         mount /dev/${MD}a ${IMGMNT}
445
446         if [ ${MFSROOT} = 'yes' ]
447         then
448                 echo "${TS} Creating MFS root..."
449                 # Update is not done yet
450                 #mkdir -p ${WORKDIR}/usr/local/bin/
451                 #cp -p ${CURRENTDIR}/update/update ${WORKDIR}/usr/local/bin/
452                 rm ${WORKDIR}/etc/fstab
453                 cd ${WORKDIR} && find . -print | sed '/kernel/ d' | cpio -dump ${IMGMNT} || true
454                 umount ${IMGMNT}
455                 dd if=/dev/${MD} of=${CURRENTDIR}/mfsroot.img           
456                 gzip -9 < ${CURRENTDIR}/mfsroot.img > ${CURRENTDIR}/mfsroot.gz
457                 rm ${CURRENTDIR}/mfsroot.img
458                 mount /dev/${MD}a ${IMGMNT}
459                 rm -rf ${IMGMNT}/*
460                 cp -rp ${WORKDIR}/boot ${IMGMNT}
461                 rm ${IMGMNT}/boot/device.hints
462                 ( \
463                 echo 'set vfs.root.mountfrom="ufs:/dev/md0a"' ; \
464                 echo 'set bootfile="/boot/kernel/kernel"' ; \
465                 sed -e  '/^#/ d' -e 's/^/set /' < ${WORKDIR}/boot/device.hints ; \
466                 echo 'load /boot/kernel/kernel' ; \
467                 echo 'echo Loading mfsroot' ; \
468                 echo 'load -t mfs_root /mfsroot' ;\
469                 echo 'boot' ; \
470                 ) > ${IMGMNT}/boot/loader.rc
471                 mv ${CURRENTDIR}/mfsroot.gz ${IMGMNT}
472         else
473                 ( cd ${WORKDIR} && find . -print | cpio -dump ${IMGMNT} ) || true
474         fi
475
476         df ${IMGMNT}
477         sleep 1
478         umount ${IMGMNT}
479
480         dd if=/dev/${MD} of=${CURRENTDIR}/${IMG} bs=64k
481
482         rm -vf ${VNODEFILE}
483         rm -rvf ${IMGMNT}
484         mdconfig -d -u ${MD}
485         echo ""
486         echo "${TS} Done!"
487         echo "${TS} Your configuration options were saved in ${FULLFILENAME}"
488         echo "${TS} You can see your build log in ${HOME}/tinybsd.log"
489         echo "${TS} Your final image is in ${CURRENTDIR}/${IMG}"
490         echo "${TS} Now use dd(1) to write it."
491
492 }
493
494 ##########################
495 # run things
496
497 ##########################################
498 ## The actual program
499 ##########################################
500 getargs $*
501 setdefaults
502 # Load as many of the configuration options as we can
503 loadconfig
504 saveconfig
505
506 # Rotate build log
507 rotate_buidlog
508
509 # Now start logging.
510 (
511   # Do the build
512   prework
513   check_alt_imgname
514   create_tree
515   copy_binaries
516   install_ports
517   make_kernel
518   copy_libraries
519   symlinks
520   deinstall_ports
521   create_etc
522   create_ssh_keys
523   personal_conf
524   create_image
525 #set +xv
526 ) 2>&1 |tee -a  ${HOME}/tinybsd.log
527