Magellan Linux

Annotation of /branches/mlivecdbuild-1_x_branch/mlivecdbuild2.sh

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1531 - (hide annotations) (download) (as text)
Fri Nov 4 11:34:30 2011 UTC (12 years, 6 months ago) by niro
Original Path: trunk/mlivecdbuild/mlivecdbuild2.sh
File MIME type: application/x-sh
File size: 15474 byte(s)
-support systemd and dracut
1 niro 346 #!/bin/bash
2    
3     # some default settings - gets overidden with the profile config
4 niro 360 CDPROFILE="$2"
5 niro 346 [[ -z ${CDPROFILE} ]] && CDPROFILE="default"
6     LIVECDROOT="/mnt/MLIVECDBUILD/${CDPROFILE}"
7     CDCHROOTDIR="${LIVECDROOT}/chroot"
8     CDISONAME="livecd-${CDPROFILE}.iso"
9     CDISOROOT="${LIVECDROOT}/isoroot"
10     CDKERNELNAME="magelive"
11     CDHOSTNAME="livecd-${CDPROFILE}"
12     MAGERC="/etc/mage.rc"
13     MAGE_PROFILE="$(basename $(readlink /etc/mage-profile))"
14     #TOOLCHAIN=toolchain
15     BASESYSTEM=livecdsystem26
16     CDID="mlcd-$(date +%F-%k%M)"
17    
18     # global profile pathes
19     PROFILES_DIR="/usr/lib/mlivecdbuild/profiles"
20     GLOBAL_PROFILE="${PROFILES_DIR}/global"
21    
22 niro 1422 # get full path to isolinux.bin, may vary on multilib systems
23     if [[ -f /usr/share/syslinux/isolinux.bin ]]
24 niro 1402 then
25 niro 1422 ISOLINUX_BIN=/usr/share/syslinux/isolinux.bin
26     elif [[ -f /usr/lib64/mkinitrd/isolinux.bin ]]
27     then
28 niro 1402 ISOLINUX_BIN=/usr/lib64/mkinitrd/isolinux.bin
29     else
30     ISOLINUX_BIN=/usr/lib/mkinitrd/isolinux.bin
31     fi
32    
33 niro 346 die() { echo "ERROR: $@"; exit 1; }
34    
35     # get_profile $filename
36     get_profile()
37     {
38     local file="$1"
39    
40     if [[ -z ${file} ]] || [[ ! -e ${PROFILES_DIR}/${CDPROFILE}/${file} ]]
41     then
42     echo "${GLOBAL_PROFILE}/${file}"
43     return 0
44     fi
45    
46     echo "${PROFILES_DIR}/${CDPROFILE}/${file}"
47     }
48    
49     bootstrap_system()
50     {
51     mage-bootstrap \
52     --root "${CDCHROOTDIR}" \
53     --magerc "${MAGERC}" \
54     --profile "${MAGE_PROFILE}" \
55     --toolchain "${TOOLCHAIN}" \
56     --basesystem "${BASESYSTEM}" \
57     || die "bootstrapping toolchain"
58     }
59    
60 niro 360 custom_services()
61     {
62     local cmd="$1"
63     local services="$2"
64 niro 1403 local systemdcmd
65 niro 360
66     case ${cmd} in
67 niro 471 add|del|default)
68     # add given services from profile
69     if [[ -n ${services} ]]
70     then
71     local i
72     for i in ${services}
73     do
74 niro 1403 # systemd
75     if [[ -x ${CDCHROOTDIR}/sbin/systemctl ]]
76     then
77     case ${cmd} in
78     add) chroot ${CDCHROOTDIR} systemctl enable ${i} ;;
79     del) chroot ${CDCHROOTDIR} systemctl disable ${i} ;;
80 niro 1531 default)
81     # convert targets
82     case ${i} in
83     2|3) service="multi-user.target" ;;
84     5) service="graphical.target" ;;
85     esac
86     chroot ${CDCHROOTDIR} systemctl enable ${i} ;;
87 niro 1403 esac
88     fi
89     # busybox and sysvinit
90     if [[ -x ${CDCHROOTDIR}/sbin/rc-config ]]
91     then
92     MROOT="${CDCHROOTDIR}" rc-config ${cmd} ${i} || die "rc ${cmd} ${i}"
93     fi
94 niro 471 done
95     fi
96     ;;
97 niro 360 *) die "custom_services: unkown command ${cmd}";;
98     esac
99     }
100    
101     add_initrc()
102     {
103     local var="$1"
104    
105     # sanity checks
106 niro 473 [[ -z ${CDCHROOTDIR} ]] && die "\$CDCHROOTDIR not given."
107 niro 360 echo "${var}" >> ${CDCHROOTDIR}/.installrc || die "add_initrc() adding \$var"
108     }
109    
110     custom_packages()
111     {
112     local cmd="$1"
113     local packages="$2"
114    
115     case ${cmd} in
116 niro 471 install|uninstall)
117     if [[ -n ${packages} ]]
118     then
119     :> ${CDCHROOTDIR}/.installrc
120 niro 472
121     # respect proxies
122     [[ -n ${http_proxy} ]] && add_initrc "export http_proxy=${http_proxy}"
123     [[ -n ${ftp_proxy} ]] && add_initrc "export ftp_proxy=${ftp_proxy}"
124     [[ -n ${no_proxy} ]] && add_initrc "export no_proxy=${no_proxy}"
125    
126 niro 580 # do not auto-start any services!
127     add_initrc "export MAGE_BOOTSTRAP=true"
128 niro 863 add_initrc 'die() { if [ $? -eq 1 ]; then echo "ERROR: $@"; exit 1; fi; }'
129 niro 580
130 niro 471 local i
131     for i in ${packages}
132     do
133 niro 863 add_initrc "mage ${cmd} ${i} || die ${i}"
134 niro 471 done
135     add_initrc "mage clean"
136    
137     # now run the .installrc script
138     mount -t proc proc ${CDCHROOTDIR}/proc || die "mount proc"
139     mount -t sysfs sysfs ${CDCHROOTDIR}/sys || die "mount sys"
140     mount -o bind /dev ${CDCHROOTDIR}/dev || die "mount dev"
141     chroot ${CDCHROOTDIR} /bin/bash -i /.installrc || die "chr00ting"
142     umount ${CDCHROOTDIR}/dev || die "umount dev"
143     umount ${CDCHROOTDIR}/proc || die "umount proc"
144     umount ${CDCHROOTDIR}/sys || die "umount sys"
145     [ -f ${CDCHROOTDIR}/.installrc ] && rm ${CDCHROOTDIR}/.installrc
146     fi
147     ;;
148 niro 360 *) die "custom_packages: unkown command ${cmd}";;
149     esac
150     }
151    
152     read_config()
153     {
154     local file="$1"
155     local pkg
156    
157     ( cat ${file}; echo ) | while read pkg
158     do
159     case "${pkg}" in
160     \#*|"") continue ;;
161     esac
162     echo "${pkg}"
163     done
164     }
165    
166 niro 346 prepare_iso()
167     {
168     echo Preparing LiveCD ISO Image ...
169    
170     # fixes some issues with xfree/xorg xkb
171 niro 473 if [[ -L ${CDCHROOTDIR}/etc/X11/xkb ]] && [[ -d /usr/X11R6/lib/X11/xkb ]]
172 niro 346 then
173     rm ${CDCHROOTDIR}/etc/X11/xkb || die
174     mv ${CDCHROOTDIR}/usr/X11R6/lib/X11/xkb ${CDCHROOTDIR}/etc/X11 || die
175     ln -s ../../../../etc/X11/xkb ${CDCHROOTDIR}/usr/X11R6/lib/X11/xkb || die
176     fi
177    
178 niro 1403 # only on sysvinit or busybox systems
179     if [[ -x ${CDCHROOTDIR}/sbin/rc-config ]]
180     then
181     install -m 0644 $(get_profile inittab) ${CDCHROOTDIR}/etc/inittab || die
182     fi
183 niro 1446 if [[ -x ${CDCHROOTDIR}/bin/systemctl ]]
184     then
185 niro 1531 # check lock group on systemd systems
186 niro 1446 if [[ -z $(chroot ${CDCHROOTDIR} getent group lock) ]]
187     then
188 niro 1531 echo "adding missing group 'lock'"
189 niro 1446 chroot ${CDCHROOTDIR} groupadd -g 54 lock
190     fi
191 niro 1531 # dbus plugdev group
192     if [[ -z $(chroot ${CDCHROOTDIR} getent group plugdev) ]]
193     then
194     echo "adding missing group 'plugdev'"
195     chroot ${CDCHROOTDIR} groupadd -g 302 plugdev
196     fi
197     # dbus messagebus group
198     if [[ -z $(chroot ${CDCHROOTDIR} getent group messagebus) ]]
199     then
200     echo "adding missing group 'messagebus'"
201     chroot ${CDCHROOTDIR} groupadd -g 300 messagebus
202     fi
203     # dbus messagebus user
204     if [[ -z $(chroot ${CDCHROOTDIR} getent passwd messagebus) ]]
205     then
206     echo "adding missing user 'messagebus'"
207     chroot ${CDCHROOTDIR} useradd -u 300 -g messagebus -d /dev/null -s /bin/false messagebus
208     fi
209 niro 1446 fi
210 niro 346 install -m 0644 $(get_profile fstab) ${CDCHROOTDIR}/etc/fstab || die
211     install -m 0644 $(get_profile motd) ${CDCHROOTDIR}/etc/motd || die
212     install -m 0644 $(get_profile issue) ${CDCHROOTDIR}/etc/issue || die
213 niro 712 install -m 0644 $(get_profile net.eth0) ${CDCHROOTDIR}/etc/conf.d/net.eth0 || die
214 niro 346 echo "${CDHOSTNAME}" > ${CDCHROOTDIR}/etc/hostname || die
215    
216     echo Setting up services ...
217    
218 niro 1531 # install systemd default services
219     if [[ -x ${CDCHROOTDIR}/bin/systemctl ]]
220     then
221     # install tmpfs /tmp and /var/tmp
222     install -m 0644 $(get_profile tmp.mount) ${CDCHROOTDIR}/lib/systemd/system/ || die
223     install -m 0644 $(get_profile var-tmp.mount) ${CDCHROOTDIR}/lib/systemd/system/ || die
224     # enable them
225     ln -snf ../tmp.mount ${CDCHROOTDIR}/lib/systemd/system/local-fs.target.wants/tmp.mount || die
226     ln -snf ../var-tmp.mount ${CDCHROOTDIR}/lib/systemd/system/local-fs.target.wants/var-tmp.mount || die
227    
228     install -m 0644 $(get_profile getty) ${CDCHROOTDIR}/etc/conf.d/getty || die
229    
230     custom_services add getty@.service
231     custom_services add remote-fs.target
232     # disable readahead
233     custom_services del systemd-readahead-replay.service
234     custom_services del systemd-readahead-collect.service
235     fi
236    
237 niro 978 # # add hardware detection
238 niro 1403 # if [[ -x ${CDCHROOTDIR}/sbin/rc-config ]]
239     # then
240     # MROOT="${CDCHROOTDIR}" rc-config add hwdetect || die "rc add hwdetect"
241     # fi
242 niro 346
243     # del checkfs
244 niro 1403 if [[ -x ${CDCHROOTDIR}/sbin/rc-config ]]
245     then
246     MROOT="${CDCHROOTDIR}" rc-config del checkfs || die "rc del checkfs"
247     fi
248 niro 346
249 niro 360 # add custom packages
250     [[ -n ${ADD_PACKAGES} ]] && custom_packages install "${ADD_PACKAGES}"
251     [ -f $(get_profile add_packages) ] && custom_packages install "$(read_config $(get_profile add_packages))"
252    
253     # del custom packages
254     [[ -n ${DEL_PACKAGES} ]] && custom_packages uninstall "${DEL_PACKAGES}"
255     [ -f $(get_profile del_packages) ] && custom_packages uninstall "$(read_config $(get_profile del_packages))"
256    
257     # add given services from profile
258     [[ -n ${ADD_SERVICES} ]] && custom_services add "${ADD_SERVICES}"
259     [ -f $(get_profile add_services) ] && custom_services add "$(read_config $(get_profile add_services))"
260    
261     # del given services from profile
262     [[ -n ${DEL_SERVICES} ]] && custom_services del "${DEL_SERVICES}"
263     [ -f $(get_profile del_services) ] && custom_services del "$(read_config $(get_profile del_services))"
264    
265     # setup default runlevel
266     [[ -n ${DEFAULT_RUNLEVEL} ]] && custom_services default "${DEFAULT_RUNLEVEL}"
267    
268     if [ -f $(get_profile prepare_custom) ]
269     then
270     echo Running custom user script ...
271     source $(get_profile prepare_custom) || die "running custom user script"
272     fi
273    
274 niro 346 echo Cleaning unwanted files ...
275 niro 1403 # do this only if not a symlink!
276     if [[ ! -L ${CDCHROOTDIR}/etc/mtab ]]
277     then
278     :> ${CDCHROOTDIR}/etc/mtab || die "whiping /etc/mtab"
279     fi
280 niro 360 [ -f ${CDCHROOTDIR}/root/.bash_history ] && rm ${CDCHROOTDIR}/root/.bash_history
281 niro 346 }
282    
283     generate_rootfs()
284     {
285 niro 1403 local loopdev
286     local size
287    
288     if [ -f ${LIVECDROOT}/loop/LiveOS/ext3fs.img ]
289     then
290     rm ${LIVECDROOT}/loop/LiveOS/ext3fs.img || die
291     fi
292     if [ -f ${CDISOROOT}/LiveOS/squashfs.img ]
293     then
294     rm ${CDISOROOT}/LiveOS/squashfs.img
295     fi
296     if [ -f ${CDISOROOT}/livecdrootfs.sqsh ]
297     then
298     rm ${CDISOROOT}/livecdrootfs.sqsh
299     fi
300    
301 niro 346 echo Generating squashfs compressed rootfs loopfile ...
302 niro 1403 if [[ -x ${CDCHROOTDIR}/sbin/dracut ]]
303     then
304     install -d ${LIVECDROOT}/loop/{LiveOS,mnt} || die
305 niro 346
306 niro 1403 # get the actual size of the chroot
307 niro 1531 size=$(du -s ${LIVECDROOT}/chroot | sed 's:^\(.*\)[[:space:]].*:\1:')
308 niro 1403
309     # generate a ext3fs file for devicemapper
310     dd if=/dev/zero of=${LIVECDROOT}/loop/LiveOS/ext3fs.img bs=1024 count=$(( ${size} + 10 )) || die
311     # create a filesystem
312     mkfs.ext3 -L "_${CDID}_EXT3" -m 1 -b 1024 -F ${LIVECDROOT}/loop/LiveOS/ext3fs.img || die
313     # set mount_counts and check_intervals to 0
314     # set dir_index top, to speed up thing with hashed b-trees
315     # allow acls too
316     tune2fs -c0 -i0 -Odir_index -ouser_xattr,acl ${LIVECDROOT}/loop/LiveOS/ext3fs.img || die
317    
318     # losetup the device
319     loopdev=$(losetup -f)
320     [[ -z ${loopdev} ]] && die "No unused loopdev found. Maybe you want 'modprobe loop'?"
321    
322     # mount the image
323     losetup ${loopdev} ${LIVECDROOT}/loop/LiveOS/ext3fs.img || die
324     mount ${loopdev} ${LIVECDROOT}/loop/mnt || die
325    
326     # copy everything to the image file and preserve permissions
327     ( cd ${CDCHROOTDIR} && tar cpf - . ) | ( cd ${LIVECDROOT}/loop/mnt && tar xvpf - )
328    
329     # now umount everything and create the squashfs image
330     umount ${LIVECDROOT}/loop/mnt || die
331     losetup -d ${loopdev} || die
332     # remove mount to not ending up in the squashfs image
333     if [[ -d ${LIVECDROOT}/loop/mnt ]]
334     then
335     rm -r ${LIVECDROOT}/loop/mnt || die
336     fi
337     mksquashfs ${LIVECDROOT}/loop ${LIVECDROOT}/livecdrootfs.sqsh || die
338    
339     # final cleanup
340     if [[ -d ${LIVECDROOT}/loop ]]
341     then
342     rm -r ${LIVECDROOT}/loop || die
343     fi
344     else
345     mksquashfs ${CDCHROOTDIR} ${LIVECDROOT}/livecdrootfs.sqsh || die
346     fi
347    
348 niro 346 echo Moving rootfs loopfile to isoroot ...
349     install -d ${CDISOROOT}
350 niro 1403 if [[ -x ${CDCHROOTDIR}/sbin/dracut ]]
351     then
352     install -d ${CDISOROOT}/LiveOS
353     mv ${LIVECDROOT}/livecdrootfs.sqsh ${CDISOROOT}/LiveOS/squashfs.img
354     else
355     mv ${LIVECDROOT}/livecdrootfs.sqsh ${CDISOROOT}
356     fi
357 niro 346 }
358    
359     install_bootloader()
360     {
361     echo Installing Bootloader ...
362    
363     # iso linux binary
364     install -d ${CDISOROOT}/isolinux
365 niro 1402 install ${ISOLINUX_BIN} ${CDISOROOT}/isolinux || die
366 niro 346
367     # kernel
368     local kimg="$(basename $(readlink ${CDCHROOTDIR}/boot/vmlinuz))"
369     install ${CDCHROOTDIR}/boot/${kimg} ${CDISOROOT}/isolinux/${CDKERNELNAME} || die
370    
371     install -m 0644 $(get_profile isolinux.cfg) ${CDISOROOT}/isolinux || die
372     install -m 0644 $(get_profile boot.lss) ${CDISOROOT}/isolinux || die
373     install -m 0644 $(get_profile boot.msg) ${CDISOROOT}/isolinux || die
374     install -m 0644 $(get_profile help.msg) ${CDISOROOT}/isolinux || die
375 niro 1531 # support the new layout too
376     if [[ -f $(get_profile index.msg) ]]
377     then
378     install -m 0644 $(get_profile index.msg) ${CDISOROOT}/isolinux || die
379     fi
380     if [[ -f $(get_profile debug.msg) ]]
381     then
382     install -m 0644 $(get_profile debug.msg) ${CDISOROOT}/isolinux || die
383     fi
384 niro 346
385     return 0
386     }
387    
388     generate_initrd()
389     {
390     local CHROOTSH="$(mktemp -p ${CDCHROOTDIR})"
391    
392 niro 1403 is_loc_mounted "${CDCHROOTDIR}/sys" || mount -t sysfs sysfs ${CDCHROOTDIR}/sys
393     is_loc_mounted "${CDCHROOTDIR}/proc" || mount -t proc proc ${CDCHROOTDIR}/proc
394     is_loc_mounted "${CDCHROOTDIR}/dev" || mount -o bind /dev ${CDCHROOTDIR}/dev
395    
396 niro 346 echo Generating initrd image ...
397     echo '#!/bin/bash' > ${CHROOTSH} || die
398 niro 1403 echo 'export LC_ALL=C' >> ${CHROOTSH} || die
399 niro 346 echo 'kv="$(readlink /boot/vmlinuz)"' >> ${CHROOTSH} || die
400     echo 'kv="${kv/kernel-}/"' >> ${CHROOTSH} || die
401 niro 1403 # prefer dracut
402     echo 'if [[ -x /sbin/dracut ]]' >> ${CHROOTSH} || die
403     echo 'then' >> ${CHROOTSH} || die
404     echo ' dracut -v -f /initrd.gz ${kv}' >> ${CHROOTSH} || die
405     echo 'else' >> ${CHROOTSH} || die
406     echo ' mkinitrd-livecd -f --initramfs /initrd.gz ${kv}' >> ${CHROOTSH} || die
407     echo 'fi' >> ${CHROOTSH} || die
408 niro 346 chmod +x ${CHROOTSH} || die
409     chroot ${CDCHROOTDIR} /$(basename ${CHROOTSH}) || die
410     [[ -f ${CHROOTSH} ]] && rm ${CHROOTSH} || die
411    
412 niro 1403 is_loc_mounted "${CDCHROOTDIR}/dev" && umount ${CDCHROOTDIR}/dev
413     is_loc_mounted "${CDCHROOTDIR}/proc" && umount ${CDCHROOTDIR}/proc
414     is_loc_mounted "${CDCHROOTDIR}/sys" && umount ${CDCHROOTDIR}/sys
415    
416 niro 346 # move initrd to isoroot
417     install -d ${CDISOROOT}/isolinux || die
418     mv ${CDCHROOTDIR}/initrd.gz ${CDISOROOT}/isolinux || die
419     }
420    
421     generate_iso()
422     {
423     echo Generating ISO Image ...
424     install -d ${CDISOROOT}
425     pushd ${CDISOROOT} &&
426     mkisofs -rock \
427     -full-iso9660-filenames \
428     -allow-leading-dots \
429     -disable-deep-relocation \
430     -output ${LIVECDROOT}/${CDISONAME} \
431     -eltorito-boot isolinux/isolinux.bin \
432     -eltorito-catalog isolinux/boot.cat \
433     -no-emul-boot \
434     -boot-load-size 4 \
435     -boot-info-table \
436     -volid "${CDID}" \
437     ${CDISOROOT} #&> /dev/null
438     popd
439     }
440    
441     enter_livecd()
442     {
443 niro 1403 is_loc_mounted "${CDCHROOTDIR}/sys" || mount -t sysfs sysfs ${CDCHROOTDIR}/sys
444     is_loc_mounted "${CDCHROOTDIR}/proc" || mount -t proc proc ${CDCHROOTDIR}/proc
445     is_loc_mounted "${CDCHROOTDIR}/dev" || mount -o bind /dev ${CDCHROOTDIR}/dev
446 niro 346
447     chroot ${CDCHROOTDIR} \
448     /usr/bin/env -i \
449     HOME=/root \
450     TERM=$TERM PS1='\u:\w\$ ' \
451     PATH=/bin:/usr/bin:/sbin:/usr/sbin \
452 niro 472 http_proxy=${http_proxy} \
453     ftp_proxy=${ftp_proxy} \
454     no_proxy=${no_proxy} \
455 niro 346 /bin/bash -i
456 niro 609
457 niro 1403 is_loc_mounted "${CDCHROOTDIR}/dev" && umount ${CDCHROOTDIR}/dev
458     is_loc_mounted "${CDCHROOTDIR}/proc" && umount ${CDCHROOTDIR}/proc
459     is_loc_mounted "${CDCHROOTDIR}/sys" && umount ${CDCHROOTDIR}/sys
460 niro 346 }
461    
462 niro 1403 is_loc_mounted()
463     {
464     local filesys
465     local i
466     filesys=$1
467    
468     i="$(cat /proc/mounts | grep " ${filesys} " | cut -d ' ' -f2)"
469     [[ ${i} != ${filesys} ]] && return 1
470    
471     return 0
472     }
473    
474     trap_exit()
475     {
476     is_loc_mounted "${CDCHROOTDIR}/dev" && umount ${CDCHROOTDIR}/dev
477     is_loc_mounted "${CDCHROOTDIR}/proc" && umount ${CDCHROOTDIR}/proc
478     is_loc_mounted "${CDCHROOTDIR}/sys" && umount ${CDCHROOTDIR}/sys
479     }
480    
481 niro 360 usage()
482     {
483     echo "Usage: $(basename $0) [command] [profile] ..."
484     echo
485     echo "Commands:"
486     echo " bootstrap - bootstraps the rootfs for the livecd"
487     echo " prepare - prepare the rootfs to run from a livecd"
488     echo " rootfs - generates the squashfs rootfs image"
489     echo " initrd - generates a livecd suitable initrd"
490     echo " bootloader - installs the bootloader"
491     echo " isogen - generate the final livecd iso image"
492     echo " all - runs all tasks to get a livecd from zero"
493 niro 472 echo " enter - enters the rootfs of a livecd"
494 niro 360 echo
495     echo " for example '$(basename $0) all default'"
496     echo " creates a livecd using the default profile."
497     echo
498     }
499    
500 niro 1403 # set some proper traps
501     trap "trap_exit" SIGINT SIGQUIT
502    
503 niro 346 # source profile config - overrides all other vars
504     [ -f ${PROFILES_DIR}/${CDPROFILE}/config ] && . ${PROFILES_DIR}/${CDPROFILE}/config
505    
506 niro 360 case $1 in
507     bootstrap) bootstrap_system;;
508     prepare) prepare_iso;;
509     rootfs) generate_rootfs;;
510     initrd) generate_initrd;;
511     bootloader) install_bootloader;;
512     isogen) generate_iso;;
513     all)
514     bootstrap_system
515     prepare_iso
516     generate_rootfs
517     generate_initrd
518     install_bootloader
519 niro 713 generate_iso
520 niro 360 ;;
521 niro 472 enter) enter_livecd ;;
522 niro 360 *|'') usage;;
523     esac