3 # purpose : create a node-specific CD ISO image
5 # NOTE (see also bootcd/build.sh)
6 # If you run your own myplc instance, and you dont need to
7 # customize the bootcd, you might wish to use bootcd/build.sh
9 # However cdcustom.sh might turn out useful if
10 # (*) you only have an iso image and nothing else
11 # (*) or you want to generate several iso images in a single run
12 # (*) or you run myplc rpm, but need to customize the bootcd image,
13 # because the myplc rpm does not come with the required sources
15 # given a (generic, node-independant) CD ISO image, and a (set of)
16 # node-specific config file(s), this command creates a new almost
17 # identical ISO image with the node config file embedded as
18 # /usr/boot/plnode.txt in the overlay.img image
19 # the output iso images are named after the nodes, and stored in .
22 # here is how we do this
23 # for efficiency, we do only once:
24 # (*) mount the generic iso
25 # (*) copy it into a temp dir
26 # (*) unzip/unarchive overlay image into another temp dir
27 # then for each node, we
28 # (*) insert plnode.txt at the right place
29 # (*) rewrap a gzipped/cpio overlay.img, that we push onto the
31 # (*) rewrap this into an iso image
32 # and cleanup/umount everything
34 ######## Customizing the BootCD
35 # In addition we check (once) for
36 # (*) a file called 'bootcd.img' in the current dir
37 # (*) a directory named 'bootcd/' in the current dir
38 # if any of those is present, we use this - presumably custom - stuff to
39 # replace original bootcd.img from the CD
41 # (*) if the .img is present, it is taken as-is,
42 # (*) if not but bootcd/ is present, bootcd.img is refreshed and used
43 # All this is done only once at startup because it typically
44 # takes 40s to recompress bootcd.img
46 # allow local bootcd/ to hold only patched files
47 # and get the rest from the CD's bootcd.img
49 ######## Implementation note
50 # in a former release it was possible to perform faster by
51 # loopback-mounting the generic iso image
52 # Unfortunately mkisofs cannot graft a file that already exists on the
53 # original tree (so overlay.img cannot be overridden)
54 # to make things worse we cannot loopback-mount the cpio-gzipped
55 # overlay image either, so all this stuff is way more complicated
57 # It's still pretty fast, unless recompressing a bootcd.img is required
60 COMMAND=$(basename $0 .sh)
64 echo "Usage: $0 generic-iso node-config [node-configs]"
65 echo "Creates a node-specific ISO image"
66 echo "with the node-specific config file embedded as /boot/plnode.txt"
70 ### read config file in a subshell and echoes host_name
71 function host_name () {
72 export CONFIG=$1; shift
73 ( . "$CONFIG" ; echo $HOST_NAME )
77 OVERLAY_IMAGE=overlay.img
80 # use local bootcd/ or bootcd.img if existing
81 BOOTCD_IMAGE=bootcd.img
83 ## arg-provided generic iso
87 # resulting iso image and log
90 ## mount points and temps
91 ISO_MOUNT=/tmp/$COMMAND-$$-mount
92 ISO_ROOT=/tmp/$COMMAND-$$-iso
93 OVERLAY_ROOT=/tmp/$COMMAND-$$-overlay
94 # node-dep cpio/gzip image
97 CPIO_OARGS="-oc --quiet"
98 CPIO_IARGS="-id --quiet"
101 # export VERBOSE=true for enabling this
102 function verbose () {
103 if [ -n "$VERBOSE" ] ; then
108 function message () { echo "$COMMAND : $@" ; }
109 function message-n () { echo -n "$COMMAND : $@" ; }
110 function message-done () { echo Done ; }
111 function error () { echo "$COMMAND : ERROR $@ - exiting" ; exit 1 ;}
115 function startup () {
117 [[ -n "$DEBUG" ]] && set -x
119 # lazy : run only once
120 [[ -n "$STARTED_UP" ]] && return
121 message "starting up"
124 [ ! -f "$ISO_GENERIC" ] && error "Could not find template ISO image"
125 [ -d "$ISO_MOUNT" ] && error "$ISO_MOUNT already exists"
126 [ -d "$ISO_ROOT" ] && error "$ISO_ROOT already exists"
127 [ -d "$OVERLAY_ROOT" ] && error "$OVERLAY_ROOT already exists"
129 verbose "Creating temp dirs"
130 mkdir -p $ISO_MOUNT $ISO_ROOT $OVERLAY_ROOT
131 verbose "Mounting generic ISO $ISO_GENERIC under $ISO_MOUNT"
132 mount -o ro,loop $ISO_GENERIC $ISO_MOUNT
134 ### DONT!! use tar for duplication
135 message "Duplicating ISO image in $ISO_ROOT"
136 (cd $ISO_MOUNT ; find . | cpio $CPIO_PARGS $ISO_ROOT )
138 # use local bootcd.img or bootcd/ if existing
139 message-n "Checking for custom $BOOTCD_ROOT in . "
140 if [ -d $BOOTCD_ROOT -a -f $BOOTCD_IMAGE ] ; then
141 message-n " using $BOOTCD_IMAGE as-is "
142 elif [ -d $BOOTCD_ROOT -a ! -f $BOOTCD_IMAGE ] ; then
143 message-n "yes, making img .. "
144 (cd $BOOTCD_ROOT ; find . | cpio $CPIO_OARGS) | gzip -9 > $BOOTCD_IMAGE
146 if [ -f $BOOTCD_IMAGE ] ; then
147 message-n "pushing onto $ISO_ROOT.. "
148 cp $BOOTCD_IMAGE $ISO_ROOT/$BOOTCD_IMAGE
152 message "Extracting generic overlay image in $OVERLAY_ROOT"
153 gzip -d -c "$ISO_ROOT/$OVERLAY_IMAGE" | ( cd "$OVERLAY_ROOT" ; cpio $CPIO_IARGS )
159 function node_cleanup () {
160 verbose "Cleaning node-dependent cpio image"
161 rm -rf "$NODE_OVERLAY"
165 function cleanup () {
167 echo "$COMMAND : cleaning up"
168 [[ -n "$DEBUG" ]] && set -x
170 verbose "Cleaning overlay image"
171 rm -rf "$OVERLAY_ROOT"
172 verbose "Cleaning ISO image"
174 verbose "Cleaning node-dep overlay image"
175 rm -f "$NODE_OVERLAY"
176 verbose "Unmounting $ISO_MOUNT"
177 umount "$ISO_MOUNT" 2> /dev/null
183 echo "$COMMAND : Aborting"
184 message "Cleaning $NODE_ISO"
191 trap abort int hup quit err
194 [[ -n "$DEBUG" ]] && set -x
196 [[ -z "$@" ]] && usage
197 ISO_GENERIC=$1; shift
199 [[ -z "$@" ]] && usage
201 # perform that later (lazily)
202 # so that (1st) node-dep checking are done before we bother to unpack
205 for NODE_CONFIG in "$@" ; do
207 NODENAME=$(host_name $NODE_CONFIG)
208 if [ -z "$NODENAME" ] ; then
209 message "HOST_NAME not found in $NODE_CONFIG - skipped"
213 message "$COMMAND : dealing with node $NODENAME"
215 NODE_ISO="$NODENAME.iso"
216 NODE_LOG="$NODENAME.log"
217 NODE_OVERLAY="$NODENAME.img"
220 if [ -e "$NODE_ISO" ] ; then
221 message "$NODE_ISO exists, please remove first - skipped" ; continue
223 if [ ! -f "$NODE_CONFIG" ] ; then
224 message "Could not find node-specifig config - skipped" ; continue
229 verbose "Pushing node config into overlay image"
230 mkdir -p $OVERLAY_ROOT/$PLNODE_PATH
231 cp "$NODE_CONFIG" $OVERLAY_ROOT/$PLNODE_PATH/$PLNODE
233 echo "$COMMAND : Creating overlay image for $NODENAME"
234 (cd "$OVERLAY_ROOT" ; find . | cpio $CPIO_OARGS) | gzip -9 > $NODE_OVERLAY
236 message-n "Pushing custom overlay image "
237 cp "$NODE_OVERLAY" "$ISO_ROOT/$OVERLAY_IMAGE"
240 message "Refreshing isolinux.cfg"
241 # Calculate ramdisk size (total uncompressed size of both archives)
242 ramdisk_size=$(gzip -l $ISO_ROOT/bootcd.img $ISO_ROOT/overlay.img | tail -1 | awk '{ print $2; }') # bytes
243 # keep safe, provision for cpio's block size
244 ramdisk_size=$(($ramdisk_size / 1024 + 1)) # kilobytes
246 # Write isolinux configuration
247 cat > $ISO_ROOT/isolinux.cfg <<EOF
249 APPEND ramdisk_size=$ramdisk_size initrd=bootcd.img,overlay.img root=/dev/ram0 rw
255 message-n "Writing custom image, log on $NODE_LOG .. "
256 mkisofs -o "$NODE_ISO" -R -allow-leading-dots -J -r -b isolinux.bin \
257 -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table \
258 "$ISO_ROOT" > "$NODE_LOG" 2>&1
263 message "CD ISO image for $NODENAME in $NODE_ISO"