]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/tools/tinybsd/tinybsd
This commit was generated by cvs2svn to compensate for changes in r173682,
[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/BIND.chroot.dist -p ${WORKDIR}
271         mtree -deU -f /etc/mtree/BSD.usr.dist -p ${WORKDIR}/usr
272         mtree -deU -f /etc/mtree/BSD.local.dist -p ${WORKDIR}/usr/local
273         mtree -deU -f /etc/mtree/BSD.var.dist -p ${WORKDIR}/var
274 }
275
276 copy_binaries() {
277         cd ${CURRENTDIR}/conf/${CONF}
278
279         for file in `cat ${BASEFILE} | grep -v "#" | \
280                 cut -f1 -d":" | sort | uniq` ; do
281                 echo "${TS} Copying "/${file}" to "${WORKDIR}/${file} 
282                 cp -fp /${file} ${WORKDIR}/${file} ;
283         done
284 }
285
286 install_ports() {
287         for portname in `cat ${PORTSFILE} | grep -v '#'` ; do
288             cd ${PORTSDIR}/${portname}
289             pkgname=`make -V PKGNAME`
290             pkg_info -VQ ${pkgname}
291             install=`echo $?`
292             if [ ${install} -eq 0 ] ; then
293                echo "$portname is already installed..."
294                create_missingdir
295                copy_ports
296               else
297                 make install clean
298                 create_missingdir
299                 copy_ports
300             fi
301         done
302 }
303
304 create_missingdir() {
305 pkg_info -L ${pkgname} | egrep -v '(Information|Files|www|share|doc|man|include)' | sort | uniq >> ${PKGDIRS}
306         for dir in `cat ${PKGDIRS}`; do
307           if [ ! -d `dirname ${WORKDIR}/${dir}` ] ; then
308             mkdir -p `dirname ${WORKDIR}/${dir}`
309           fi
310         done
311         rm ${PKGDIRS}
312 }
313
314 copy_ports() {
315 pkg_info -L ${pkgname} | egrep -v '(Information|Files|www|share|doc|man|include)' >> ${PKGFILES}
316         for port in `cat ${PKGFILES}` ; do
317                 echo "${TS} Copying "${port}" to "${WORKDIR}${port}
318                 cp -fp ${port} ${WORKDIR}${port} ;
319         done
320 }
321
322 make_kernel() {
323         echo "${TS} Building customized tiny beastie kernel... "
324         cp -p ${CURRENTDIR}/conf/${CONF}/${KERNCONF} /usr/src/sys/i386/conf
325         cd /usr/src
326         make buildkernel KERNCONF=${KERNCONF} || exit 1
327         gzip -9 /usr/obj/usr/src/sys/${KERNCONF}/kernel
328         install ${DEFINSTARGS} /usr/obj/usr/src/sys/${KERNCONF}/kernel.gz ${WORKDIR}/boot/kernel/
329         install ${DEFINSTARGS} \
330           /usr/obj/usr/src/sys/${KERNCONF}/modules/usr/src/sys/modules/acpi/acpi/acpi.ko \
331             ${WORKDIR}/boot/kernel
332         install -o 0 -g 0 -m 444 /sys/i386/conf/GENERIC.hints ${WORKDIR}/boot/device.hints
333 }
334
335 copy_libraries() {
336         TDEPFILE="`mktemp -t deps`"
337         TDEPFILES="`mktemp -t depsymlnk`"
338
339         cd ${CURRENTDIR}/conf/${CONF}
340         for file in `cat ${BASEFILE} ${PKGFILES} | grep -v "#" | cut -f1 -d":"`; do
341                 ldd -f "%p\n" /${file} >> ${TDEPFILE} ; # don't worry on progs been "not dynamic"
342         done
343
344         rm ${PKGFILES}
345
346         for libdeplib in `cat ${TDEPFILE} | sort | uniq`; do
347                 ldd -f "%p\n" /${libdeplib} >> ${TDEPFILE} ;
348         done
349
350         for pamdep in `ls -1 /usr/lib/pam*`; do
351                 echo $pamdep >> ${TDEPFILE} ;
352                 ldd -f "%p\n" /${pamdep} >> ${TDEPFILE} ;
353         done    
354
355         for lib in `cat ${TDEPFILE} | sort | uniq`; do
356                 echo "${TS} Copying "${lib}" to "${WORKDIR}${lib}
357                 cp -fp ${lib} ${WORKDIR}${lib} ;
358         done
359
360         for depsymlink in `cat ${TDEPFILE}`; do
361                 echo "${TS} Checking if ${depsymlink} is a symbolic link"
362                 /bin/ls -l $depsymlink | grep "\->" | awk '{print $11":"$9}' >> ${TDEPFILES}
363         done
364
365         for i in `cat ${TDEPFILES}`; do
366                 SOURCE_FILE=`echo $i | awk -F ":" '{print $1}'`
367                 TARGET_FILE=`echo $i | awk -F ":" '{print $2}'`
368
369                 echo "${TS} Unlinking ${WORKDIR}${TARGET_FILE}"
370                 chroot ${WORKDIR} /bin/chflags 0 ${TARGET_FILE}
371                 chroot ${WORKDIR} /bin/rm -f ${TARGET_FILE}
372
373                 echo "${TS} Symlinking ${SOURCE_FILE} to ${TARGET_FILE}"
374                 chroot ${WORKDIR} /bin/ln -s ${SOURCE_FILE} ${TARGET_FILE}
375         done
376
377         echo -n "${TS} Unlinking "
378         rm -fv ${TDEPFILE} ${TDEPFILES}
379 }
380
381 deinstall_ports() {
382         for portname in `cat ${PORTSFILE} | grep -v '#'` ; do
383             cd ${PORTSDIR}/${portname}    
384              if [ $? -ne ${install} ] ; then
385                make deinstall
386              fi
387         done
388 }
389
390 create_etc() {
391         cd /usr/src/etc/sendmail/
392         make freebsd.cf freebsd.submit.cf
393
394         cd /usr/src/etc/
395         mkdir -p ${WORKDIR}/var/named/etc/namedb
396         make distribution DESTDIR=${WORKDIR}
397 }
398
399 create_ssh_keys() {
400         echo "Creating ssh keys..."
401         ssh-keygen -t rsa1 -b 1024  -f ${WORKDIR}/etc/ssh/ssh_host_key -N ''
402         ssh-keygen -t dsa -f ${WORKDIR}/etc/ssh/ssh_host_dsa_key -N ''
403         ssh-keygen -t rsa -f ${WORKDIR}/etc/ssh/ssh_host_rsa_key -N ''
404 }
405
406 personal_conf() {
407         echo "${TS} Copying your custom configuration on conf/ ..."
408         for custom in `find ${CURRENTDIR}/conf/${CONF}/ -type d -depth 1 \! -name CVS`; do
409                 cp -Rp ${custom}/* ${WORKDIR}/${custom#${CURRENTDIR}/conf/${CONF}/}/
410         done
411
412         if [ -f ${CURRENTDIR}/conf/${CONF}/boot.config ]; then
413                 cp ${CURRENTDIR}/conf/${CONF}/boot.config ${WORKDIR}/boot.config
414         fi
415 }
416
417 symlinks() {
418 #set -xv
419         for i in `cat ${BASEFILE} ${PORTSFILE} | grep -v "#" | grep ":"`; do
420                 SOURCE_FILE=`echo $i | awk -F ":" {'print $1'}`
421                 TARGET_FILE=`echo $i | awk -F ":" {'print $2'}`
422                 chroot ${WORKDIR} /bin/ln -vs /${SOURCE_FILE} ${TARGET_FILE}
423         done
424 #set +xv
425 }
426
427
428 create_image() {
429         VNODEFILE=`mktemp -t tinybsd`
430         IMGMNT=`mktemp -d -t tinybsd`
431
432         dd if=/dev/zero of=${VNODEFILE} count=${SECTUNIT}
433
434         MD=`mdconfig -a -t vnode -f ${VNODEFILE} -x ${SECTRACK} -y ${TRACKCYL}`
435
436         diskinfo -v /dev/${MD}
437
438         fdisk -I /dev/${MD}
439         fdisk /dev/${MD}
440
441         cp -p /boot/boot0 ${WORKDIR}/boot/boot0
442         bsdlabel -w -B /dev/${MD}
443         newfs -O2 -U /dev/${MD}a
444
445         mount /dev/${MD}a ${IMGMNT}
446
447         if [ ${MFSROOT} = 'yes' ]
448         then
449                 echo "${TS} Creating MFS root..."
450                 # Update is not done yet
451                 #mkdir -p ${WORKDIR}/usr/local/bin/
452                 #cp -p ${CURRENTDIR}/update/update ${WORKDIR}/usr/local/bin/
453                 rm ${WORKDIR}/etc/fstab
454                 cd ${WORKDIR} && find . -print | sed '/kernel/ d' | cpio -dump ${IMGMNT} || true
455                 umount ${IMGMNT}
456                 dd if=/dev/${MD} of=${CURRENTDIR}/mfsroot.img           
457                 gzip -9 < ${CURRENTDIR}/mfsroot.img > ${CURRENTDIR}/mfsroot.gz
458                 rm ${CURRENTDIR}/mfsroot.img
459                 mount /dev/${MD}a ${IMGMNT}
460                 rm -rf ${IMGMNT}/*
461                 cp -rp ${WORKDIR}/boot ${IMGMNT}
462                 rm ${IMGMNT}/boot/device.hints
463                 ( \
464                 echo 'set vfs.root.mountfrom="ufs:/dev/md0a"' ; \
465                 echo 'set bootfile="/boot/kernel/kernel"' ; \
466                 sed -e  '/^#/ d' -e 's/^/set /' < ${WORKDIR}/boot/device.hints ; \
467                 echo 'load /boot/kernel/kernel' ; \
468                 echo 'echo Loading mfsroot' ; \
469                 echo 'load -t mfs_root /mfsroot' ;\
470                 echo 'boot' ; \
471                 ) > ${IMGMNT}/boot/loader.rc
472                 mv ${CURRENTDIR}/mfsroot.gz ${IMGMNT}
473         else
474                 ( cd ${WORKDIR} && find . -print | cpio -dump ${IMGMNT} ) || true
475         fi
476
477         df ${IMGMNT}
478         sleep 1
479         umount ${IMGMNT}
480
481         dd if=/dev/${MD} of=${CURRENTDIR}/${IMG} bs=64k
482
483         rm -vf ${VNODEFILE}
484         rm -rvf ${IMGMNT}
485         mdconfig -d -u ${MD}
486         echo ""
487         echo "${TS} Done!"
488         echo "${TS} Your configuration options were saved in ${FULLFILENAME}"
489         echo "${TS} You can see your build log in ${HOME}/tinybsd.log"
490         echo "${TS} Your final image is in ${CURRENTDIR}/${IMG}"
491         echo "${TS} Now use dd(1) to write it."
492
493 }
494
495 ##########################
496 # run things
497
498 ##########################################
499 ## The actual program
500 ##########################################
501 getargs $*
502 setdefaults
503 # Load as many of the configuration options as we can
504 loadconfig
505 saveconfig
506
507 # Rotate build log
508 rotate_buidlog
509
510 # Now start logging.
511 (
512   # Do the build
513   prework
514   check_alt_imgname
515   create_tree
516   copy_binaries
517   install_ports
518   make_kernel
519   copy_libraries
520   symlinks
521   deinstall_ports
522   create_etc
523   create_ssh_keys
524   personal_conf
525   create_image
526 #set +xv
527 ) 2>&1 |tee -a  ${HOME}/tinybsd.log
528